using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Xml;
using System.Globalization;
using System.IO;
using System.Xml.Schema;
using System.Xml.XPath;
using System.ServiceModel;
using System.ServiceModel.Channels;
using WCF = System.ServiceModel.Channels;
using System.ServiceModel.Configuration;

using System.CodeDom;
using System.CodeDom.Compiler;
using System.ServiceModel.Description;
using System.Runtime.Serialization;
//using System.Web.Services.Description;
using System.Configuration;
using System.Reflection;

using Microsoft.MSE.Catalog.Contracts;
using MSEContracts = Microsoft.MSE.Catalog.Contracts;
using Microsoft.MSE;
using SvcDescription = System.Web.Services.Description.ServiceDescription;
using WSDL = System.Web.Services.Description;
using System.Data.SqlTypes;

namespace Microsoft.MSE.Catalog.Module
{
    public class DAL
    {
        private static NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;

        public static Guid GetIDFromName(string entityName, EntityClass entityClass, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Guid entityID;
            const string sprocname = "[ServiceEngine].[GetIDFromName]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter entityNameParam = new SqlParameter("@EntityName", SqlDbType.NVarChar, 400);
                    SqlParameter entityTypeIDParam = new SqlParameter("@EntityTypeID", SqlDbType.Int);
                    SqlParameter entityIDParam = new SqlParameter("@EntityID", SqlDbType.UniqueIdentifier);
                    entityIDParam.Direction = ParameterDirection.Output;

                    cmd.CommandType = CommandType.StoredProcedure;
                    entityNameParam.Value = entityName;
                    entityTypeIDParam.Value = (int)entityClass;
                    cmd.Parameters.Add(entityNameParam);
                    cmd.Parameters.Add(entityTypeIDParam);
                    cmd.Parameters.Add(entityIDParam);

                    cmd.ExecuteNonQuery();

                    if (entityIDParam.Value != DBNull.Value)
                    {
                        entityID = (Guid)entityIDParam.Value;
                    }
                    else
                    {
                        entityID = Guid.Empty;
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return entityID;

        }

        public static EndpointList ListEndpointsForRuntimeServerID(Guid runtimeServerID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            EndpointList list = new EndpointList();
            const string sprocname = "[ServiceEngine].[ListEndpointsForRuntimeServerID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter runtimeServerIDParam = new SqlParameter("@RuntimeServerID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    runtimeServerIDParam.Value = runtimeServerID;
                    cmd.Parameters.Add(runtimeServerIDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Endpoints = new List<EndpointListElement>();
                            while (reader.Read())
                            {
                                EndpointListElement element = new EndpointListElement();
                                element.ID = reader.GetGuid(0);
                                element.URI = reader.GetString(1);
                                element.Port = reader.GetInt32(2);
                                if (reader.IsDBNull(3))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(3);
                                }
                                list.Endpoints.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static EndpointList ListEndpoints(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            EndpointList list = new EndpointList();
            const string sprocname = "[ServiceEngine].[ListEndpoints]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Endpoints = new List<EndpointListElement>();
                            while (reader.Read())
                            {
                                EndpointListElement element = new EndpointListElement();
                                element.ID = reader.GetGuid(0);
                                element.URI = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Endpoints.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }
        
        public static EndpointList ListEndpointsForPolicyID(Guid policyID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            EndpointList list = new EndpointList();
            const string sprocname = "[ServiceEngine].[ListEndpointsForPolicyID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = policyID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Endpoints = new List<EndpointListElement>();
                            while (reader.Read())
                            {
                                EndpointListElement element = new EndpointListElement();
                                element.ID = reader.GetGuid(0);
                                element.URI = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Endpoints.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }
        
        public static EndpointList ListEndpointsForBindingID(Guid bindingID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            EndpointList list = new EndpointList();
            const string sprocname = "[ServiceEngine].[ListEndpointsForBindingID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = bindingID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Endpoints = new List<EndpointListElement>();
                            while (reader.Read())
                            {
                                EndpointListElement element = new EndpointListElement();
                                element.ID = reader.GetGuid(0);
                                element.URI = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Endpoints.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static Endpoint GetEndpoint(Guid ID, Guid RuntimeServerID, bool provideWSDL, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Endpoint endpoint = new Endpoint();            
            const string sprocname = "[ServiceEngine].[GetEndpoint]";
            const string sprocname2 = "[ServiceEngine].[GetRuntimeServer]";

            if (RuntimeServerID == Guid.Empty) provideWSDL = false;

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                


                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            endpoint.ID = reader.GetGuid(0);
                            endpoint.Path = reader.GetString(1);
                            endpoint.Binding = GetMSEBinding(reader.GetGuid(2), txn, conn);
                            if (reader.IsDBNull(3))
                            {
                                endpoint.Policy = null;
                            }
                            else
                            {
                                endpoint.Policy = GetPolicy(reader.GetGuid(3), txn, conn);
                            }
                            if (reader.IsDBNull(4))
                            {
                                endpoint.Description = null;
                            }
                            else
                            {
                                endpoint.Description = reader.GetString(4);
                            }
                            if (reader.IsDBNull(5))
                            {
                                endpoint.NamespaceURI = null;
                            }
                            else
                            {
                                endpoint.NamespaceURI = reader.GetString(5);
                            }
                            endpoint.TestCallsAccepted = reader.GetBoolean(6);
                            endpoint.AutoOperationPubUpdate = reader.GetBoolean(7);
                            endpoint.AutoOperationActivationUpdate = reader.GetBoolean(8);
                            if (reader.IsDBNull(9))
                            {
                                endpoint.Configuration = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(9).CreateReader());
                                endpoint.Configuration = xdoc.DocumentElement;
                            }
                            if (reader.IsDBNull(10))
                            {
                                endpoint.ServiceName = null;
                            }
                            else
                            {
                                endpoint.ServiceName = reader.GetString(10);
                            }
                            if (reader.IsDBNull(11))
                            {
                                endpoint.Port = 0;
                            }
                            else
                            {
                                endpoint.Port = reader.GetInt32(11);
                            }

                            endpoint.PubOpVersionsList = ListPublishedOperationsForEndpoint(ID, txn, conn);
                            endpoint.AssocOpVersionsList = ListAssociatedOperationsForEndpoint(ID, txn, conn);

                            Binding binding = BindingHelper.DeserializeBinding(endpoint.Binding.BindingConfig);
                            
                            // Provide WSDL only if demanded
                            if (provideWSDL)
                            {
                                String epHost = "";
                                using (SqlCommand cmd2 = new SqlCommand(sprocname2, conn, txn))
                                {
                                    SqlParameter IDParam2 = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                                    cmd2.CommandType = CommandType.StoredProcedure;
                                    IDParam2.Value = RuntimeServerID;
                                    cmd2.Parameters.Add(IDParam2);

                                    using (SqlDataReader reader2 = cmd2.ExecuteReader())
                                    {
                                        if (reader2.HasRows)
                                        {
                                            reader2.Read();
                                            epHost += reader2.IsDBNull(10) ? null : reader2.GetString(10);
                                        }
                                    }
                                }
                                if (endpoint.Port != 0)
                                    epHost += ":" + Convert.ToString(endpoint.Port);

                                endpoint.Address = epHost + @"/" + endpoint.Path;

                               //endpoint.WSDL = GenerateWSDLForEndpoint(endpoint, endpoint.Address, txn, conn);
                               endpoint.WSDL = CreateWSDLFromEndpointMetadata(endpoint, txn, conn);
                            }
                            else
                            {
                                // Just set the address to the path to maintain compatibility
                                endpoint.Address = endpoint.Path;
                            }

                            endpoint.UddiAssociations = ListEndpointUddiAssociation(ID, txn, conn);
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return endpoint;

        }

        public static OperationVersionList ListAssociatedOperationsForEndpoint(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationVersionList list = new OperationVersionList();
            const string sprocname = "[ServiceEngine].[ListAssociatedOperationsForEndpoint]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.OperationVersions = new List<OperationVersionListElement>();
                            while (reader.Read())
                            {
                                OperationVersionListElement element = new OperationVersionListElement();
                                element.ID = reader.GetGuid(0);
                                element.OperationName = reader.GetString(1);
                                VersionNumber version = new VersionNumber();
                                version.Major = reader.GetInt32(2).ToString();
                                version.Minor = reader.GetInt32(3).ToString();
                                version.Build = reader.GetInt32(4).ToString();
                                version.Qfe = reader.GetInt32(5).ToString();
                                element.Version = version;
                                list.OperationVersions.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static OperationVersionList ListPublishedOperationsForEndpoint(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationVersionList list = new OperationVersionList();

            const string sprocname = "[ServiceEngine].[ListPublishedOperationsForEndpoint]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.OperationVersions = new List<OperationVersionListElement>();
                            while (reader.Read())
                            {
                                OperationVersionListElement element = new OperationVersionListElement();
                                element.ID = reader.GetGuid(0);
                                element.OperationName = reader.GetString(1);
                                VersionNumber version = new VersionNumber();
                                version.Major = reader.GetInt32(2).ToString();
                                version.Minor = reader.GetInt32(3).ToString();
                                version.Build = reader.GetInt32(4).ToString();
                                version.Qfe = reader.GetInt32(5).ToString();
                                element.Version = version;
                                list.OperationVersions.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<EndpointAssociatedUddi> ListEndpointUddiAssociation(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[ListEndpointUddiAssociation]";
            List<EndpointAssociatedUddi> uddiAssociations = new List<EndpointAssociatedUddi>();

            try
            {

                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            EndpointAssociatedUddi endpointAssociatedUddi = new EndpointAssociatedUddi();
                            endpointAssociatedUddi.UddiAssociationID = reader.GetGuid(0);
                            endpointAssociatedUddi.EndpointID = reader.GetGuid(1);
                            endpointAssociatedUddi.TModelKey = reader.GetString(2);
                            endpointAssociatedUddi.ServiceKey = reader.GetString(3);
                            endpointAssociatedUddi.BindingKey = reader.GetString(4);
                            endpointAssociatedUddi.WsdlUrl = reader.GetString(5);
                            endpointAssociatedUddi.BindingUrl = reader.GetString(6);
                            endpointAssociatedUddi.RuntimeServerID = reader.GetGuid(7);
                            uddiAssociations.Add(endpointAssociatedUddi);
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return uddiAssociations;

        }

        public static Policy GetPolicy(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Policy policy = new Policy();
            const string sprocname = "[ServiceEngine].[GetPolicy]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            policy.ID = reader.GetGuid(0);
                            policy.Name = reader.GetString(1);
                            XmlDocument xdoc = new XmlDocument();
                            xdoc.Load(reader.GetSqlXml(2).CreateReader());
                            policy.WSPolicy = xdoc.DocumentElement;
                            if (reader.IsDBNull(3))
                            {
                                policy.Description = null;
                            }
                            else
                            {
                                policy.Description = reader.GetString(3);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return policy;

        }
        
        public static void DeleteEndpoint(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteEndpoint]";

            List<Guid> runtimeServerIDs = new List<Guid>();
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                try
                {
                    eventData = DAL.ListRuntimeServersForEndpointID(ID, txn, conn);
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in DeleteEndpoint.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }
                #endregion

                // Remove any UDDI associations 
                eventData.ForEach(item => { RemoveEndPointFromUddi(ID, item.RuntimeServerId, txn, conn); });

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                //send notification to affected runtimes
                RepositoryChangeManager.RecordChange(DBEvents.EndpointsUpdated, DBChangeType.Delete, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();


            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static Endpoint UpdateEndpoint(Endpoint endpoint, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateEndpoint]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }
                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                try
                {
                    eventData = DAL.ListRuntimeServersForEndpointID(endpoint.ID, txn, conn);
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in UpdateEndpoint.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter PortParam = new SqlParameter("@Port", SqlDbType.Int);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter NamespaceURIParam = new SqlParameter("@NamespaceURI", SqlDbType.NText);
                    SqlParameter ServiceNameParam = new SqlParameter("@ServiceName", SqlDbType.NText);
                    SqlParameter ConfigurationParam = new SqlParameter("@Configuration", SqlDbType.Xml);
                    SqlParameter TestCallsAcceptedParam = new SqlParameter("@TestCallsAccepted", SqlDbType.Bit);
                    SqlParameter AutoOperationPubUpdateParam = new SqlParameter("@AutoOperationPubUpdate", SqlDbType.Bit);
                    SqlParameter AutoOperationActivationUpdateParam = new SqlParameter("@AutoOperationActivationUpdate", SqlDbType.Bit);


                    if (endpoint.Policy != null)
                    {
                        PolicyIDParam.Value = endpoint.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = endpoint.ID;
                    NameParam.Value = endpoint.Path;
                    if (endpoint.Binding != null)
                    {
                        if (endpoint.Binding.ID.Equals(Guid.Empty))
                        {
                            BindingIDParam.Value = CreateMSEBinding(endpoint.Binding, txn, conn);
                        }
                        else
                        {
                            BindingIDParam.Value = endpoint.Binding.ID;
                        }
                    }
                    else
                    {
                        throw new ApplicationException("UpdateEndpoint requires Binding, but no Binding was supplied");
                    }
                    PortParam.Value = endpoint.Port;
                    DescriptionParam.Value = endpoint.Description;
                    NamespaceURIParam.Value = endpoint.NamespaceURI;
                    ServiceNameParam.Value = endpoint.ServiceName;
                    TestCallsAcceptedParam.Value = endpoint.TestCallsAccepted;
                    AutoOperationPubUpdateParam.Value = endpoint.AutoOperationPubUpdate;
                    AutoOperationActivationUpdateParam.Value = endpoint.AutoOperationActivationUpdate;
                    if ((endpoint.Configuration == null) || (string.IsNullOrEmpty(endpoint.Configuration.OuterXml)))
                    {
                        ConfigurationParam.Value = DBNull.Value;
                    }
                    else
                    {
                        ConfigurationParam.Value = endpoint.Configuration.OuterXml;
                    }
                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(PortParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(NamespaceURIParam);
                    cmd.Parameters.Add(ConfigurationParam);
                    cmd.Parameters.Add(ServiceNameParam);
                    cmd.Parameters.Add(TestCallsAcceptedParam);
                    cmd.Parameters.Add(AutoOperationPubUpdateParam);
                    cmd.Parameters.Add(AutoOperationActivationUpdateParam);

                    cmd.ExecuteNonQuery();
                }

                // Update any UDDI associations 
                eventData.ForEach(item => { PublishEndPointToUddi(endpoint.ID, item.RuntimeServerId, false, txn, conn); });

                //send notification to affected runtimes
                RepositoryChangeManager.RecordChange(DBEvents.EndpointsUpdated, DBChangeType.Update, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return endpoint;
        }

        public static Guid CreateEndpoint(Endpoint endpoint, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateEndpoint]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter PortParam = new SqlParameter("@Port", SqlDbType.Int);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter NamespaceURIParam = new SqlParameter("@NamespaceURI", SqlDbType.NText);
                    SqlParameter ServiceNameParam = new SqlParameter("@ServiceName", SqlDbType.NText);
                    SqlParameter ConfigurationParam = new SqlParameter("@Configuration", SqlDbType.Xml);
                    SqlParameter TestCallsAcceptedParam = new SqlParameter("@TestCallsAccepted", SqlDbType.Bit);
                    SqlParameter AutoOperationPubUpdateParam = new SqlParameter("@AutoOperationPubUpdate", SqlDbType.Bit);
                    SqlParameter AutoOperationActivationUpdateParam = new SqlParameter("@AutoOperationActivationUpdate", SqlDbType.Bit);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    // Remove Uri Scheme
                    NameParam.Value = RemoveUriScheme(endpoint.Path);
                    if (endpoint.Policy != null)
                    {
                        PolicyIDParam.Value = endpoint.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }
                    if (endpoint.Binding != null)
                    {
                        if (endpoint.Binding.ID.Equals(Guid.Empty))
                        {
                            BindingIDParam.Value = CreateMSEBinding(endpoint.Binding, txn, conn);
                        }
                        else
                        {
                            BindingIDParam.Value = endpoint.Binding.ID;
                        }
                    }
                    else
                    {
                        throw new ApplicationException("CreateEndpoint requires Binding, but no Binding was supplied");
                    }
                    DescriptionParam.Value = endpoint.Description;
                    PortParam.Value = endpoint.Port;
                    NamespaceURIParam.Value = endpoint.NamespaceURI;
                    ServiceNameParam.Value = endpoint.ServiceName;
                    TestCallsAcceptedParam.Value = endpoint.TestCallsAccepted;
                    AutoOperationPubUpdateParam.Value = endpoint.AutoOperationPubUpdate;
                    AutoOperationActivationUpdateParam.Value = endpoint.AutoOperationActivationUpdate;
                    if ((endpoint.Configuration == null) || (string.IsNullOrEmpty(endpoint.Configuration.OuterXml)))
                    {
                        ConfigurationParam.Value = DBNull.Value;
                    }
                    else
                    {
                        ConfigurationParam.Value = endpoint.Configuration.OuterXml;
                    }
                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(PortParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(NamespaceURIParam);
                    cmd.Parameters.Add(ConfigurationParam);
                    cmd.Parameters.Add(ServiceNameParam);
                    cmd.Parameters.Add(TestCallsAcceptedParam);
                    cmd.Parameters.Add(AutoOperationPubUpdateParam);
                    cmd.Parameters.Add(AutoOperationActivationUpdateParam);

                    cmd.ExecuteNonQuery();

                    ID = (Guid)IDParam.Value;
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static RuntimeServerList ListRuntimeServers(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            RuntimeServerList list = new RuntimeServerList();
            const string sprocname = "[ServiceEngine].[ListRuntimeServers]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.RuntimeServers = new List<RuntimeServerListElement>();
                            while (reader.Read())
                            {
                                RuntimeServerListElement element = new RuntimeServerListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.RuntimeServers.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static ChannelList ListChannels(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ChannelList list = new ChannelList();
            const string sprocname = "[ServiceEngine].[ListChannels]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Channels = new List<ChannelListElement>();
                            while (reader.Read())
                            {
                                ChannelListElement element = new ChannelListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Channels.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }
        
        public static ChannelList ListChannelsForPolicyID(Guid policyID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ChannelList list = new ChannelList();
            const string sprocname = "[ServiceEngine].[ListChannelsForPolicyID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = policyID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Channels = new List<ChannelListElement>();
                            while (reader.Read())
                            {
                                ChannelListElement element = new ChannelListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Channels.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }
        
        public static ChannelList ListChannelsForBindingID(Guid bindingID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ChannelList list = new ChannelList();
            const string sprocname = "[ServiceEngine].[ListChannelsForBindingID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = bindingID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Channels = new List<ChannelListElement>();
                            while (reader.Read())
                            {
                                ChannelListElement element = new ChannelListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Channels.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static RuntimeServer GetRuntimeServer(Guid ID, bool provideWSDL, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            RuntimeServer runtimeServer = new RuntimeServer();
            const string sprocname = "[ServiceEngine].[GetRuntimeServer]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            runtimeServer.ID = reader.GetGuid(0);
                            runtimeServer.Name = reader.GetString(1);

                            runtimeServer.Name = reader.IsDBNull(1) ? null : reader.GetString(1);

                            runtimeServer.CatalogURI = reader.IsDBNull(2) ? null : reader.GetString(2);
                            runtimeServer.CatalogBinding = reader.IsDBNull(3) ? null : GetMSEBinding(reader.GetGuid(3), txn, conn);

                            runtimeServer.NotificationURI = reader.IsDBNull(4) ? null : reader.GetString(4);
                            runtimeServer.NotificationBinding = reader.IsDBNull(5) ? null : GetMSEBinding(reader.GetGuid(5), txn, conn);

                            runtimeServer.BrokerURI = reader.IsDBNull(6) ? null : reader.GetString(6);
                            runtimeServer.BrokerBinding = reader.IsDBNull(7) ? null : GetMSEBinding(reader.GetGuid(7), txn, conn);

                            runtimeServer.ListenerURI = reader.IsDBNull(8) ? null : reader.GetString(8);
                            runtimeServer.ListenerBinding = reader.IsDBNull(9) ? null : GetMSEBinding(reader.GetGuid(9), txn, conn);

                            runtimeServer.HostName = reader.IsDBNull(10) ? null : reader.GetString(10);
                            runtimeServer.Description = reader.IsDBNull(11) ? null : reader.GetString(11);

                            runtimeServer.Endpoints = new List<Endpoint>();
                            EndpointList endpointList = ListEndpointsForRuntimeServerID(ID, txn, conn);
                            if (endpointList.Endpoints != null)
                            {
                                foreach (EndpointListElement element in endpointList.Endpoints)
                                {
                                    runtimeServer.Endpoints.Add(GetEndpoint(element.ID, runtimeServer.ID, provideWSDL, txn, conn));
                                }
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return runtimeServer;

        }

        public static void DeleteRuntimeServer(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteRuntimeServer]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                //NOTE: No change tracking implemented here since db integrity requires removing endpoints from runtime first

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void DeleteChannel(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteChannel]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                //NOTE: No change tracking implemented here since db integrity requires removing operation versions first

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                //Delete all entity Policies SGK
                DeletePoliciesFromEntity(ID, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static RuntimeServer UpdateRuntimeServer(RuntimeServer runtimeServer, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateRuntimeServer]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter CatalogURIParam = new SqlParameter("@CatalogURI", SqlDbType.NVarChar, 400);
                    SqlParameter CatalogBindingParam = new SqlParameter("@CatalogBindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter NotificationURIParam = new SqlParameter("@NotificationURI", SqlDbType.NVarChar, 400);
                    SqlParameter NotificationBindingParam = new SqlParameter("@NotificationBindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter HostNameParam = new SqlParameter("@HostName", SqlDbType.NVarChar, 400);
                    SqlParameter BrokerURIParam = new SqlParameter("@BrokerURI", SqlDbType.NVarChar, 400);
                    SqlParameter BrokerBindingParam = new SqlParameter("@BrokerBindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter ListenerParam = new SqlParameter("@ListenerURI", SqlDbType.NVarChar, 400);
                    SqlParameter ListenerBindingParam = new SqlParameter("@ListenerBindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = runtimeServer.ID;
                    NameParam.Value = runtimeServer.Name;

                    if (string.IsNullOrEmpty(runtimeServer.CatalogURI) == false)
                    {
                        CatalogURIParam.Value = runtimeServer.CatalogURI;
                        CatalogBindingParam.Value = runtimeServer.CatalogBinding.ID;
                    }
                    else
                    {
                        CatalogURIParam.Value = null;
                        CatalogBindingParam.Value = null;
                    }

                    if (string.IsNullOrEmpty(runtimeServer.NotificationURI) == false)
                    {
                        NotificationURIParam.Value = runtimeServer.NotificationURI;
                        NotificationBindingParam.Value = runtimeServer.NotificationBinding.ID;
                    }
                    else
                    {
                        NotificationURIParam.Value = null;
                        NotificationBindingParam.Value = null;
                    }

                    if (string.IsNullOrEmpty(runtimeServer.BrokerURI) == false)
                    {
                        BrokerURIParam.Value = runtimeServer.BrokerURI;
                        BrokerBindingParam.Value = runtimeServer.BrokerBinding.ID;
                    }
                    else
                    {
                        BrokerURIParam.Value = null;
                        BrokerBindingParam.Value = null;
                    }

                    if (string.IsNullOrEmpty(runtimeServer.ListenerURI) == false)
                    {
                        ListenerParam.Value = runtimeServer.ListenerURI;
                        ListenerBindingParam.Value = runtimeServer.ListenerBinding.ID;
                    }
                    else
                    {
                        ListenerParam.Value = null;
                        ListenerBindingParam.Value = null;
                    }

                    if (string.IsNullOrEmpty(runtimeServer.HostName) == false)
                    {
                        HostNameParam.Value = runtimeServer.HostName;
                    }
                    else
                    {
                        HostNameParam.Value = null;
                    }

                    DescriptionParam.Value = runtimeServer.Description;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(HostNameParam);
                    cmd.Parameters.Add(CatalogURIParam);
                    cmd.Parameters.Add(NotificationURIParam);
                    cmd.Parameters.Add(BrokerURIParam);
                    cmd.Parameters.Add(ListenerParam);
                    cmd.Parameters.Add(CatalogBindingParam);
                    cmd.Parameters.Add(NotificationBindingParam);
                    cmd.Parameters.Add(BrokerBindingParam);
                    cmd.Parameters.Add(ListenerBindingParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();
                }
                #region Endpoint Association changes
                EndpointList list = ListEndpointsForRuntimeServerID(runtimeServer.ID, txn, conn);

                //remove any endpoint associations that should no longer be
                bool present = false;
                if (list.Endpoints != null)
                {
                    foreach (EndpointListElement ep in list.Endpoints)
                    {
                        present = false;
                        if (runtimeServer.Endpoints != null)
                        {
                            foreach (Endpoint xep in runtimeServer.Endpoints)
                            {
                                if (ep.ID == xep.ID)
                                    present = true;
                            }
                        }
                        if (!present)
                            RemoveEndpointFromRuntimeServer(ep.ID, runtimeServer.ID, txn, conn);
                    }
                }
                //Add any new endpoint associations
                if (runtimeServer.Endpoints != null)
                {
                    foreach (Endpoint xep in runtimeServer.Endpoints)
                    {
                        present = false;
                        if (list.Endpoints != null)
                        {
                            foreach (EndpointListElement ep in list.Endpoints)
                            {
                                if (ep.ID == xep.ID)
                                {
                                    present = true;
                                    break;
                                }
                            }
                        }
                        if (!present)
                        {
                            if (xep.ID.Equals(Guid.Empty))
                            {
                                xep.ID = CreateEndpoint(xep, txn, conn);
                            }
                            AssignEndpointToRuntimeServer(xep.ID, runtimeServer.ID, txn, conn);
                        }
                    }
                }
                #endregion

                //send notification to affected runtimes
                List<DBEventDataItem> eventData = new List<DBEventDataItem>();
                eventData.Add(new DBEventDataItem(runtimeServer.ID));
                RepositoryChangeManager.RecordChange(DBEvents.RuntimeServersUpdated, DBChangeType.Update, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();


            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return runtimeServer;
        }

        public static Guid CreateRuntimeServer(RuntimeServer runtimeServer, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateRuntimeServer]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter CatalogURIParam = new SqlParameter("@CatalogURI", SqlDbType.NVarChar, 400);
                    SqlParameter CatalogBindingParam = new SqlParameter("@CatalogBindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter NotificationURIParam = new SqlParameter("@NotificationURI", SqlDbType.NVarChar, 400);
                    SqlParameter NotificationBindingParam = new SqlParameter("@NotificationBindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter HostNameParam = new SqlParameter("@HostName", SqlDbType.NVarChar, 400);
                    SqlParameter BrokerURIParam = new SqlParameter("@BrokerURI", SqlDbType.NVarChar, 400);
                    SqlParameter BrokerBindingParam = new SqlParameter("@BrokerBindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter ListenerParam = new SqlParameter("@ListenerURI", SqlDbType.NVarChar, 400);
                    SqlParameter ListenerBindingParam = new SqlParameter("@ListenerBindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = runtimeServer.Name;

                    if (string.IsNullOrEmpty(runtimeServer.CatalogURI) == false)
                    {
                        CatalogURIParam.Value = runtimeServer.CatalogURI;
                        CatalogBindingParam.Value = runtimeServer.CatalogBinding.ID;
                    }
                    else
                    {
                        CatalogURIParam.Value = null;
                        CatalogBindingParam.Value = null;
                    }

                    if (string.IsNullOrEmpty(runtimeServer.NotificationURI) == false)
                    {
                        NotificationURIParam.Value = runtimeServer.NotificationURI;
                        NotificationBindingParam.Value = runtimeServer.NotificationBinding.ID;
                    }
                    else
                    {
                        NotificationURIParam.Value = null;
                        NotificationBindingParam.Value = null;
                    }

                    if (string.IsNullOrEmpty(runtimeServer.BrokerURI) == false)
                    {
                        BrokerURIParam.Value = runtimeServer.BrokerURI;
                        BrokerBindingParam.Value = runtimeServer.BrokerBinding.ID;
                    }
                    else
                    {
                        BrokerURIParam.Value = null;
                        BrokerBindingParam.Value = null;
                    }

                    if (string.IsNullOrEmpty(runtimeServer.ListenerURI) == false)
                    {
                        ListenerParam.Value = runtimeServer.ListenerURI;
                        ListenerBindingParam.Value = runtimeServer.ListenerBinding.ID;
                    }
                    else
                    {
                        ListenerParam.Value = null;
                        ListenerBindingParam.Value = null;
                    }

                    if (string.IsNullOrEmpty(runtimeServer.HostName) == false)
                    {
                        HostNameParam.Value = runtimeServer.HostName;                        
                    }
                    else
                    {
                        HostNameParam.Value = null;                       
                    }

                    DescriptionParam.Value = runtimeServer.Description;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(CatalogURIParam);
                    cmd.Parameters.Add(NotificationURIParam);
                    cmd.Parameters.Add(HostNameParam);
                    cmd.Parameters.Add(BrokerURIParam);
                    cmd.Parameters.Add(ListenerParam);
                    cmd.Parameters.Add(CatalogBindingParam);
                    cmd.Parameters.Add(NotificationBindingParam);
                    cmd.Parameters.Add(BrokerBindingParam);
                    cmd.Parameters.Add(ListenerBindingParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();

                    ID = (Guid)IDParam.Value;
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static Guid CreateChannel(Channel chnl, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateChannel]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter MonikerSchemaParam = new SqlParameter("@MonikerSchema", SqlDbType.Xml);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter EditorAssemblyParam = new SqlParameter("@EditorAssembly", SqlDbType.NVarChar, 4000);
                    SqlParameter EditorTypeParam = new SqlParameter("@EditorTypeName", SqlDbType.NVarChar, 4000);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = chnl.Name;
                    if (chnl.MonikerSchema != null)
                    {
                        MonikerSchemaParam.Value = chnl.MonikerSchema.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateChannel failed: MonikerSchema is a required element but was not sent");
                    }
                    BindingIDParam.Value = chnl.Binding.ID;
                    EditorAssemblyParam.Value = chnl.MonikerEditorAssemblyName;
                    EditorTypeParam.Value = chnl.MonikerEditorTypeName;
                    DescriptionParam.Value = chnl.Description;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(MonikerSchemaParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(EditorAssemblyParam);
                    cmd.Parameters.Add(EditorTypeParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();

                    ID = (Guid)IDParam.Value;
                    //Assign Policies SGK
                    if (chnl.Policies != null)
                    {
                        foreach (Policy pol in chnl.Policies)
                        {
                            if (IsGuidNullOrEmpty(pol.ID.ToString()))
                            {
                                pol.ID = CreatePolicy(pol, txn, conn);
                            }
                            AssignEntityPolicy(ID, pol.ID, txn, conn);
                        }
                    }
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static Channel UpdateChannel(Channel chnl, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateChannel]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                try
                {
                    eventData = DAL.ListRuntimeServersForChannelID(chnl.ID, txn, conn);
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in UpdateChannel.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter MonikerSchemaParam = new SqlParameter("@MonikerSchema", SqlDbType.Xml);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter EditorAssemblyParam = new SqlParameter("@EditorAssembly", SqlDbType.NVarChar, 4000);
                    SqlParameter EditorTypeParam = new SqlParameter("@EditorTypeName", SqlDbType.NVarChar, 4000);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = chnl.ID;
                    NameParam.Value = chnl.Name;
                    if (chnl.MonikerSchema != null)
                    {
                        MonikerSchemaParam.Value = chnl.MonikerSchema.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("UpdateChannel failed: MonikerSchema is a required element but was not sent");
                    }
                    BindingIDParam.Value = chnl.Binding.ID;
                    EditorAssemblyParam.Value = chnl.MonikerEditorAssemblyName;
                    EditorTypeParam.Value = chnl.MonikerEditorTypeName;
                    DescriptionParam.Value = chnl.Description;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(MonikerSchemaParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(EditorAssemblyParam);
                    cmd.Parameters.Add(EditorTypeParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();

                    ID = (Guid)IDParam.Value;
                    //Assign Policies SGK
                    DeletePoliciesFromEntity(chnl.ID, txn, conn);

                    if (chnl.Policies != null)
                    {
                        foreach (Policy pol in chnl.Policies)
                        {
                            AssignEntityPolicy(chnl.ID, pol.ID, txn, conn);
                        }
                    }
                }

                //send notification to affected runtimes
                RepositoryChangeManager.RecordChange(DBEvents.OperationsUpdated, DBChangeType.Update, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();
                
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return chnl;
        }

        public static MessengerList ListMessengers(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            MessengerList list = new MessengerList();
            const string sprocname = "[ServiceEngine].[ListMessengers]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Messengers = new List<MessengerListElement>();
                            while (reader.Read())
                            {
                                MessengerListElement element = new MessengerListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Messengers.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }
      
        public static void AssignEndpointToRuntimeServer(Guid endpointID, Guid runtimeServerID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[AssignEndpointToRuntimeServer]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter RuntimeServerIDParam = new SqlParameter("@RuntimeServerID", SqlDbType.UniqueIdentifier);
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    RuntimeServerIDParam.Value = runtimeServerID;
                    cmd.Parameters.Add(RuntimeServerIDParam);
                    EndpointIDParam.Value = endpointID;
                    cmd.Parameters.Add(EndpointIDParam);

                    cmd.ExecuteNonQuery();
                }

                // Time to publish Endpoint to UDDI 
                PublishEndPointToUddi(endpointID, runtimeServerID, false, txn, conn);

                //send notification to affected runtimes
                List<DBEventDataItem> eventData = new List<DBEventDataItem>();
                eventData.Add(new DBEventDataItem(runtimeServerID, endpointID));
                RepositoryChangeManager.RecordChange(DBEvents.EndpointsUpdated, DBChangeType.Create, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        private static Binding GetBindingFromBindingCollectionElement(
                BindingCollectionElement bindingCollectionElement,
                BindingsSection bSec)
        {
            Binding newBinding = null;
            //BindingElementCollection elements = null;
            bool isCustomBinding = false;
            try
            {
                if (null != bindingCollectionElement)
                {
                    if (bindingCollectionElement.BindingType == typeof(BasicHttpBinding))
                        newBinding = new BasicHttpBinding();
                    else if (bindingCollectionElement.BindingType == typeof(CustomBinding))
                    {
                        newBinding = new CustomBinding();
                        isCustomBinding = true;
                    }
                    else if (bindingCollectionElement.BindingType == typeof(NetMsmqBinding))
                        newBinding = new NetMsmqBinding();
                    else if (bindingCollectionElement.BindingType == typeof(NetNamedPipeBinding))
                        newBinding = new NetNamedPipeBinding();
                    else if (bindingCollectionElement.BindingType == typeof(NetPeerTcpBinding))
                        newBinding = new NetPeerTcpBinding();
                    else if (bindingCollectionElement.BindingType == typeof(WSDualHttpBinding))
                        newBinding = new WSDualHttpBinding();
                    else if (bindingCollectionElement.BindingType == typeof(WSHttpBinding))
                        newBinding = new WSHttpBinding();
                    else if (bindingCollectionElement.BindingType == typeof(NetTcpBinding))
                        newBinding = new NetTcpBinding();

                    //Should we delete all default bindings?
                    //ApplyConfiguration might alreadey do just that
                    //elements = newBinding.CreateBindingElements();
                    if (isCustomBinding)
                    {
                        CustomBindingCollectionElement cbce = bSec.CustomBinding;

                        Type bExeType = typeof(BindingElementExtensionElement);
                        MethodInfo bExeMi = bExeType.GetMethod("CreateBindingElement",
                                                BindingFlags.Instance | BindingFlags.NonPublic);

                        foreach (CustomBindingElement custBe in cbce.Bindings)
                        {
                            string strBe = custBe.Name;
                            foreach (BindingElementExtensionElement bExe in custBe)
                            {

                                ((CustomBinding)newBinding).Elements.Add(
                                            (BindingElement)bExeMi.Invoke(bExe, null));
                            }
                        }
                    }
                    else
                    {
                        foreach (IBindingConfigurationElement bEleEx in bindingCollectionElement.ConfiguredBindings)
                        {
                            bEleEx.ApplyConfiguration(newBinding);
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                //TraceHelper.TraceError("Error in GetBindingFromBindingCollectionElement. Exception: " + ex.Message);
            }
            return newBinding;
        }

        public static void RemoveEndpointFromRuntimeServer(Guid endpointID, Guid runtimeServerID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[RemoveEndpointFromRuntimeServer]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter RuntimeServerIDParam = new SqlParameter("@RuntimeServerID", SqlDbType.UniqueIdentifier);
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    RuntimeServerIDParam.Value = runtimeServerID;
                    cmd.Parameters.Add(RuntimeServerIDParam);
                    EndpointIDParam.Value = endpointID;
                    cmd.Parameters.Add(EndpointIDParam);

                    cmd.ExecuteNonQuery();
                }

                // Time to remove Endpoint to UDDI 
                RemoveEndPointFromUddi(endpointID, runtimeServerID, txn, conn);

                //send notification to affected runtimes
                List<DBEventDataItem> eventData = new List<DBEventDataItem>();
                eventData.Add(new DBEventDataItem(runtimeServerID, endpointID));
                RepositoryChangeManager.RecordChange(DBEvents.EndpointsUpdated, DBChangeType.Delete, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void RemoveEndpointsFromRuntimeServer(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[RemoveEndpointsFromRuntimeServer]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                //get list of endpoints that will be removed
                EndpointList epList = DAL.ListEndpointsForRuntimeServerID(ID, txn, conn);

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                //send notification to affected runtimes
                List<DBEventDataItem> eventData = new List<DBEventDataItem>();
                epList.Endpoints.ForEach(item => {eventData.Add(new DBEventDataItem(ID, item.ID));});
                RepositoryChangeManager.RecordChange(DBEvents.EndpointsUpdated, DBChangeType.Delete, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static Uri GetEndpointServiceUri(Endpoint endpoint, RuntimeServer runtimeServer)
        {
            Uri serviceUri;

            Binding myBinding = BindingHelper.DeserializeBinding(endpoint.Binding.BindingConfig);
            try
            {
                string uri = "";
                if (endpoint.Port > 0)
                    uri = string.Format("{0}://{1}:{2}/{3}", myBinding.Scheme,runtimeServer.HostName, endpoint.Port, endpoint.Path);
                else
                    uri = string.Format("{0}://{1}/{2}", myBinding.Scheme, runtimeServer.HostName, endpoint.Path);
                serviceUri = new Uri(uri);
            }
            catch { serviceUri = null; }

            return serviceUri;
        }

        //public static XmlElement GenerateWSDLForEndpoint(Endpoint endpoint, string epHost, SqlTransaction txn, SqlConnection conn)
        //{
        //    XmlDocument response = new XmlDocument();
        //    XmlWriterSettings writerSettings = new XmlWriterSettings();
        //    writerSettings.ConformanceLevel = ConformanceLevel.Auto;
        //    writerSettings.OmitXmlDeclaration = true;
        //    StringBuilder buffer = new StringBuilder();
        //    string virtualServiceName = null;
        //    string virtualServiceNS = null;
        //    Dictionary<string, string> prefixes = new Dictionary<string, string>();
        //    int prefixIdx = 0;
        //    StringBuilder rawschemas = new StringBuilder();
        //    Uri serviceUri;

        //    //get list of published endpoints into an operationversions list
        //    OperationVersionList publishedOpVers = DAL.ListPublishedOperationsForEndpoint(endpoint.ID, null, null);

        //    if ((((endpoint == null) || publishedOpVers == null) || publishedOpVers.OperationVersions == null))
        //        return null;

        //    if (publishedOpVers.OperationVersions.Count < 1)
        //        return null;
         
        //    //if (services.Count > 1) {
        //    //rcamacho 8/14 - Commented this out
        //    Binding myBinding = BindingHelper.DeserializeBinding(endpoint.Binding.BindingConfig);
        //    try
        //    {
        //        serviceUri = new Uri(myBinding.Scheme.ToString() + "://" + endpoint.Address);
        //    }
        //    catch(Exception ex) 
        //    { 
        //        throw new ApplicationException(string.Format("Failed to create service Uri due to error. Endpoint address may be invalid [{0}]",endpoint.Address),ex); 
        //    }
        //    Boolean Soap12 = (myBinding.MessageVersion.Envelope.ToString() == "Soap12 (http://www.w3.org/2003/05/soap-envelope)");
        //    Boolean Soap11 = (myBinding.MessageVersion.Envelope.ToString() == "Soap11 (http://schemas.xmlsoap.org/soap/envelope/)");
        //    // NZ Code Added
        //    // This flag is used to take care of any soap specific XML tags
        //    Boolean isSoap = Soap11 || Soap12;

        //    //string[] tokens = endpoint.Address.Split(new char[] { '/' }); 
        //    //int svcIdx = tokens.Length - 1;
        //    //while ((svcIdx >= 0) && (string.IsNullOrEmpty(tokens[svcIdx]))) svcIdx--;
        //    //virtualServiceName = (string.IsNullOrEmpty(tokens[svcIdx])) ? "MyService" : tokens[svcIdx];
        //    if (endpoint.ServiceName != null & endpoint.ServiceName != "")
        //        virtualServiceName = endpoint.ServiceName;
        //    else
        //    {
        //        double number;
        //        if (Double.TryParse(Convert.ToString(serviceUri.DnsSafeHost.Substring(0, 1), CultureInfo.InvariantCulture), System.Globalization.NumberStyles.Any, NumberFormatInfo.InvariantInfo, out number))
        //            virtualServiceName = "WS" + serviceUri.DnsSafeHost;
        //        else
        //            virtualServiceName = serviceUri.DnsSafeHost;
        //    }
        //    //if (char.IsDigit(virtualServiceName[0])) virtualServiceName = "VSvc_" + virtualServiceName;
        //    //virtualServiceNS = endpoint.Address;
        //    if (endpoint.NamespaceURI != null & endpoint.NamespaceURI != "")
        //        virtualServiceNS = endpoint.NamespaceURI;
        //    else
        //        virtualServiceNS = MseConstants.MSENamespace + "/" + endpoint.Binding.Name + "/" + virtualServiceName;
        //    //} else {
        //    //    virtualServiceName = services[0].Name;
        //    //    virtualServiceNS = services[0].NamespaceURI;
        //    //}

        //    using (XmlWriter writer = XmlWriter.Create(buffer, writerSettings))
        //    {
        //        writer.WriteStartElement(SC.WsdlPrefix, "definitions", SC.WsdlNS);
        //        writer.WriteAttributeString("xmlns", "tns", null, virtualServiceNS);
        //        writer.WriteAttributeString("targetNamespace", null, virtualServiceNS);
        //        writer.WriteAttributeString("xmlns", SC.XsdPrefix, null, SC.XsdNS);
        //        writer.WriteAttributeString("xmlns", SC.SoapEncPrefix, null, SC.SoapEncNS);
        //        writer.WriteAttributeString("xmlns", SC.WsdlHttpPrefix, null, SC.WsdlHttpNS);
        //        writer.WriteAttributeString("xmlns", SC.WsdlMimePrefix, null, SC.WsdlMimeNS);
        //        writer.WriteAttributeString("xmlns", SC.WsdlTMPrefix, null, SC.WsdlTMNS);
        //        if (Soap11)
        //            writer.WriteAttributeString("xmlns", SC.WsdlSoapPrefix, null, SC.WsdlSoapNS);
        //        if (Soap12)
        //            writer.WriteAttributeString("xmlns", SC.WsdlSoap12Prefix, null, SC.WsdlSoap12NS);
        //        //writer.WriteAttributeString("xmlns", SC.Soap12Prefix, null, SC.Soap12NS);
        //        //writer.WriteAttributeString("xmlns", SC.SoapPrefix, null, SC.SoapNS);
        //        prefixes.Add(virtualServiceNS, "tns");
        //        prefixes.Add(SC.WsdlNS, "wsdl");
        //        //prefixes.Add(SC.SoapNS, SC.SoapPrefix);
        //        //prefixes.Add(SC.Soap12NS, SC.Soap12Prefix);                                

        //        List<Schema> schemaList = ListSchemasForEndpoint(endpoint.ID, txn, conn);
        //        if (schemaList != null && schemaList.Count > 0)
        //        {
        //            foreach (Schema schema in schemaList)
        //            {
        //                if (!prefixes.ContainsKey(schema.NamespaceURI))
        //                {
        //                    //if (!prefixes.ContainsValue(schema.PreferredPrefix))
        //                    //{
        //                    //    prefixes.Add(schema.NamespaceURI, schema.PreferredPrefix);
        //                    //}
        //                    //else
        //                    //{ // preferred prefix already taken so use another
        //                        while (prefixes.ContainsValue(string.Format("s{0}", prefixIdx))) prefixIdx++;
        //                        prefixes.Add(schema.NamespaceURI, string.Format("s{0}", prefixIdx));
        //                    //}
        //                    //rawschemas.Append(fixSchemaSelfReferences(schema.XSD.OwnerDocument, prefixes[schema.NamespaceURI], schema.NamespaceURI));
        //                    // Fixed by Raul
        //                    XmlDocument schemaDoc = fixSchemaSelfReferences(schema.XSD.OwnerDocument, prefixes[schema.NamespaceURI], schema.NamespaceURI);
        //                    rawschemas.Append(schemaDoc.OuterXml.Replace("xs:", "xsd:").Replace("xmlns:xs=", "xmlns:xsd="));

        //                    writer.WriteAttributeString("xmlns", prefixes[schema.NamespaceURI], null, schema.NamespaceURI);
        //                }
        //            }
        //        }
        //        writer.WriteStartElement(SC.WsdlPrefix, "types", null);
        //        writer.WriteRaw(rawschemas.ToString());
        //        writer.WriteEndElement();  // end types
        //        int pt;



        //        foreach (OperationVersionListElement element in publishedOpVers.OperationVersions)
        //        {
        //            OperationVersion opVersion = GetOperationVersion(element.ID, txn, conn);
        //            string opName = opVersion.OperationName;
        //            if (opVersion.RequestMsg != null && opVersion.RequestMsg.Count > 0)
        //            {
        //                writer.WriteStartElement(SC.WsdlPrefix, "message", null);
        //                writer.WriteAttributeString("name", string.Format("{0}SoapIn", opName));
        //                pt = 0;
        //                foreach (MessagePart part in opVersion.RequestMsg)
        //                {
        //                    writer.WriteStartElement(SC.WsdlPrefix, "part", null);
        //                    // NZ Code Updated
        //                    // This is done so that WSDL for both MSE hosted and non-hsoted services look similar
        //                    writer.WriteAttributeString("name", opVersion.OperationName + "ReqPt" + (pt++));
        //                    //writer.WriteAttributeString("name", "parameters");
        //                    writer.WriteAttributeString("element", string.Format("{0}:{1}", prefixes[part.NamespaceURI], part.ElementName));
        //                    writer.WriteEndElement(); // end part
        //                }
        //                writer.WriteEndElement(); // end message
        //            }
        //            if (opVersion.ResponseMsg != null && opVersion.ResponseMsg.Count > 0)
        //            {
        //                writer.WriteStartElement(SC.WsdlPrefix, "message", null);
        //                writer.WriteAttributeString("name", string.Format("{0}SoapOut", opName));
        //                pt = 0;
        //                foreach (MessagePart part in opVersion.ResponseMsg)
        //                {
        //                    writer.WriteStartElement(SC.WsdlPrefix, "part", null);
        //                    // NZ Code Updated
        //                    // This is done so that WSDL for both MSE hosted and non-hsoted services look similar
        //                    writer.WriteAttributeString("name", opVersion.OperationName + "RespPt" + (pt++));
        //                    //writer.WriteAttributeString("name", "parameters");
        //                    writer.WriteAttributeString("element", string.Format("{0}:{1}", prefixes[part.NamespaceURI], part.ElementName));
        //                    writer.WriteEndElement(); // end part
        //                }
        //                writer.WriteEndElement(); // end message
        //            }
        //            if (opVersion.SoapFaults != null && opVersion.SoapFaults.Count > 0)
        //            {
        //                foreach (SoapFault fault in opVersion.SoapFaults)
        //                {
        //                    writer.WriteStartElement(SC.WsdlPrefix, "message", null);
        //                    writer.WriteAttributeString("name", string.Format("{0}_{1}_FaultMessage", opName, fault.Name));

        //                    writer.WriteStartElement(SC.WsdlPrefix, "part", null);
        //                    writer.WriteAttributeString("name", "detail");
        //                    //writer.WriteAttributeString("name", string.Format("{0}_{1}_FaultPart", opName, fault.Name));
        //                    writer.WriteAttributeString("element", string.Format("{0}:{1}", prefixes[fault.NamespaceURI], fault.ElementName));
        //                    writer.WriteEndElement(); // end part

        //                    writer.WriteEndElement(); // end message
        //                }
        //            }
        //        }
        //        writer.WriteStartElement(SC.WsdlPrefix, "portType", null);
        //        writer.WriteAttributeString("name", string.Format("{0}Soap", virtualServiceName));
        //        foreach (OperationVersionListElement element in publishedOpVers.OperationVersions)
        //        {
        //            OperationVersion opVersion = GetOperationVersion(element.ID, txn, conn);
        //            // A valid operation should have at least the request message defined
        //            if (opVersion.RequestMsg != null && opVersion.RequestMsg.Count > 0)
        //            {
        //                string opName = opVersion.OperationName;
        //                writer.WriteStartElement(SC.WsdlPrefix, "operation", null);
        //                writer.WriteAttributeString("name", opName);
        //                if (opVersion.RequestMsg != null && opVersion.RequestMsg.Count > 0)
        //                {
        //                    writer.WriteStartElement(SC.WsdlPrefix, "input", null);
        //                    writer.WriteAttributeString("message", string.Format("tns:{0}SoapIn", opName));
        //                    writer.WriteEndElement(); // end input
        //                }
        //                if (opVersion.ResponseMsg != null && opVersion.ResponseMsg.Count > 0)
        //                {
        //                    writer.WriteStartElement(SC.WsdlPrefix, "output", null);
        //                    writer.WriteAttributeString("message", string.Format("tns:{0}SoapOut", opName));
        //                    writer.WriteEndElement(); // end output
        //                }
        //                if (opVersion.SoapFaults != null && opVersion.SoapFaults.Count > 0)
        //                {
        //                    foreach (SoapFault fault in opVersion.SoapFaults)
        //                    {
        //                        writer.WriteStartElement(SC.WsdlPrefix, "fault", null);
        //                        writer.WriteAttributeString("message", string.Format("tns:{0}_{1}_FaultMessage", opName, fault.Name));
        //                        writer.WriteAttributeString("name", fault.Name);
        //                        writer.WriteAttributeString("Action", "http://www.w3.org/2006/05/addressing/wsdl", fault.Action);
        //                        writer.WriteEndElement(); // end output
        //                    }
        //                }
        //                writer.WriteEndElement(); // end operation
        //            }
        //            else
        //            {
        //                TraceHelper.TraceWarning("Operation Version with Name [{0}] and ID=[{1}] does not have a request message defined. It will not be included in WSDL", opVersion.OperationName, opVersion.ID);
        //            }
        //        }
        //        // NZ Code Changed
        //        // Moved this EndElement creation ot of the loop as it was causing
        //        // XmlFormat exeptions
        //        writer.WriteEndElement(); // end portType

        //        if (Soap11)
        //        {
        //            writer.WriteStartElement(SC.WsdlPrefix, "binding", null); // Soap 1.1 bindings
        //            writer.WriteAttributeString("name", string.Format("{0}Soap", virtualServiceName));
        //            writer.WriteAttributeString("type", string.Format("tns:{0}Soap", virtualServiceName));
        //            writer.WriteStartElement(SC.WsdlSoapPrefix, "binding", null);
        //            writer.WriteAttributeString("transport", SC.SoapBindingTransport);
        //            writer.WriteEndElement(); // End soap11 binding 
        //        }
        //        else if (Soap12)
        //        {
        //            writer.WriteStartElement(SC.WsdlPrefix, "binding", null); // Soap 1.2 bindings
        //            writer.WriteAttributeString("name", string.Format("{0}Soap12", virtualServiceName));
        //            writer.WriteAttributeString("type", string.Format("tns:{0}Soap", virtualServiceName));
        //            writer.WriteStartElement(SC.WsdlSoap12Prefix, "binding", null);
        //            writer.WriteAttributeString("transport", SC.SoapBindingTransport);
        //            writer.WriteEndElement(); // End soap12 binding
        //        }
        //        if (isSoap == true)
        //        {
        //            foreach (OperationVersionListElement element in publishedOpVers.OperationVersions)
        //            {
        //                OperationVersion opVersion = GetOperationVersion(element.ID, txn, conn);
        //                string opName = opVersion.OperationName;
        //                Operation op = GetOperation(opVersion.OperationID, txn, conn);
        //                writer.WriteStartElement(SC.WsdlPrefix, "operation", null);
        //                writer.WriteAttributeString("name", opName);
        //                //Add documentation of the operation description
        //                if (op.Description != null && op.Description != "")
        //                {
        //                    writer.WriteStartElement(SC.WsdlPrefix, "documentation", null);
        //                    writer.WriteAttributeString("name", "Operation Description");
        //                    writer.WriteRaw(op.Description);
        //                    writer.WriteEndElement();
        //                }
        //                //Add documentation of the version information
        //                writer.WriteStartElement(SC.WsdlPrefix, "documentation", null);
        //                writer.WriteAttributeString("name", "Version Information");
        //                writer.WriteRaw("This operation has been versioned to support revisions.  Your request will automatically be routed to the most current compatible version of this operation without explicitly specifying a version via the SOAPAction.  To explicitly invoke this version of this operation, specify the soap action as " + fullSoapAction(opVersion));
        //                writer.WriteEndElement();

        //                if (Soap11)
        //                    writer.WriteStartElement(SC.WsdlSoapPrefix, "operation", null);
        //                else if (Soap12)
        //                    writer.WriteStartElement(SC.WsdlSoap12Prefix, "operation", null);

        //                writer.WriteAttributeString("soapAction", opName);
        //                writer.WriteAttributeString("style", "document");
        //                writer.WriteEndElement(); // end soap:operation element

        //                if (opVersion.RequestMsg != null && opVersion.RequestMsg.Count > 0)
        //                {
        //                    writer.WriteStartElement(SC.WsdlPrefix, "input", null);
        //                    if (Soap11)
        //                        writer.WriteStartElement(SC.WsdlSoapPrefix, "body", null);
        //                    else if (Soap12)
        //                        writer.WriteStartElement(SC.WsdlSoap12Prefix, "body", null);
        //                    writer.WriteAttributeString("use", "literal");
        //                    writer.WriteEndElement(); // end soap:body element
        //                    writer.WriteEndElement(); // end input
        //                }
        //                if (opVersion.ResponseMsg != null && opVersion.ResponseMsg.Count > 0)
        //                {
        //                    writer.WriteStartElement(SC.WsdlPrefix, "output", null);
        //                    if (Soap11)
        //                        writer.WriteStartElement(SC.WsdlSoapPrefix, "body", null);
        //                    else if (Soap12)
        //                        writer.WriteStartElement(SC.WsdlSoap12Prefix, "body", null);
        //                    writer.WriteAttributeString("use", "literal");
        //                    writer.WriteEndElement(); // end soap:body element
        //                    writer.WriteEndElement(); // end input
        //                }
        //                if (opVersion.SoapFaults != null && opVersion.SoapFaults.Count > 0)
        //                {
        //                    foreach (SoapFault fault in opVersion.SoapFaults)
        //                    {
        //                        writer.WriteStartElement(SC.WsdlPrefix, "fault", null);
        //                        writer.WriteAttributeString("name", fault.Name);

        //                        if (Soap11)
        //                        {
        //                            writer.WriteStartElement(SC.WsdlSoapPrefix, "fault", null);
        //                        }
        //                        else if (Soap12)
        //                        {
        //                            writer.WriteStartElement(SC.WsdlSoap12Prefix, "fault", null);
        //                        }
        //                        writer.WriteAttributeString("name", fault.Name);
        //                        writer.WriteAttributeString("use", "literal");
        //                        writer.WriteEndElement(); // end WSDL:fault
        //                        writer.WriteEndElement(); // end SOAP:fault
        //                    }
        //                }
        //                writer.WriteEndElement(); // end operation

        //            }
        //        }
        //        // NZ Code Changed
        //        // Moved this EndElement creation ot of the loop as it was causing
        //        // XmlFormat exeptions
        //        writer.WriteEndElement(); // end binding

        //        if (isSoap == true)
        //        {
        //            writer.WriteStartElement(SC.WsdlPrefix, "service", null);
        //            writer.WriteAttributeString("name", string.Format("{0}", virtualServiceName));

        //            //SOAP1.1 Service Definition
        //            if (Soap11)
        //            {
        //                writer.WriteStartElement(SC.WsdlPrefix, "port", null); // Soap 11 Port
        //                writer.WriteAttributeString("name", string.Format("{0}Soap", virtualServiceName));
        //                writer.WriteAttributeString("binding", string.Format("tns:{0}Soap", virtualServiceName));
        //                writer.WriteStartElement(SC.WsdlSoapPrefix, "address", null);
        //                writer.WriteAttributeString("location", serviceUri.AbsoluteUri);
        //                writer.WriteEndElement(); // end soap:address element
        //                writer.WriteEndElement(); // end port element
        //            }
        //            //SOAP1.2 Service Definition
        //            if (Soap12)
        //            {
        //                writer.WriteStartElement(SC.WsdlPrefix, "port", null); // Soap 12 Port
        //                writer.WriteAttributeString("name", string.Format("{0}Soap12", virtualServiceName));
        //                writer.WriteAttributeString("binding", string.Format("tns:{0}Soap12", virtualServiceName));
        //                writer.WriteStartElement(SC.WsdlSoap12Prefix, "address", null);
        //                writer.WriteAttributeString("location", serviceUri.AbsoluteUri);
        //                writer.WriteEndElement(); // end soap:address element
        //                writer.WriteEndElement(); // end port element
        //                //
        //            }
        //            writer.WriteEndElement(); // end service
        //            writer.WriteEndElement(); // end definitions
        //        }
        //        writer.Flush();
        //    }

        //    response.LoadXml(buffer.ToString());

        //    return response.DocumentElement;
        //}

        public static OperationGroup GetOperationGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationGroup operationGroup = new OperationGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                operationGroup.ID = entityGroup.ID;
                operationGroup.Name = entityGroup.Name;
                operationGroup.Description = entityGroup.Description;

                operationGroup.Operations = ListOperationsByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return operationGroup;
        }

        public static SchemaGroup GetSchemaGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SchemaGroup schemaGroup = new SchemaGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                schemaGroup.ID = entityGroup.ID;
                schemaGroup.Name = entityGroup.Name;
                schemaGroup.Description = entityGroup.Description;

                schemaGroup.Schemas = ListSchemasByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return schemaGroup;
        }

        public static EndpointGroup GetEndpointGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            EndpointGroup endpointGroup = new EndpointGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                endpointGroup.ID = entityGroup.ID;
                endpointGroup.Name = entityGroup.Name;
                endpointGroup.Description = entityGroup.Description;

                endpointGroup.Endpoints = ListEndpointsByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return endpointGroup;
        }

        public static RuntimeServerGroup GetRuntimeServerGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            RuntimeServerGroup runtimeServerGroup = new RuntimeServerGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                runtimeServerGroup.ID = entityGroup.ID;
                runtimeServerGroup.Name = entityGroup.Name;
                runtimeServerGroup.Description = entityGroup.Description;

                runtimeServerGroup.RuntimeServers = ListRuntimeServersByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return runtimeServerGroup;
        }

        public static ChannelGroup GetChannelGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ChannelGroup channelGroup = new ChannelGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                channelGroup.ID = entityGroup.ID;
                channelGroup.Name = entityGroup.Name;
                channelGroup.Description = entityGroup.Description;

                channelGroup.Channels = ListChannelsByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return channelGroup;
        }
        
        public static PolicyGroup GetPolicyGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            PolicyGroup policyGroup = new PolicyGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                policyGroup.ID = entityGroup.ID;
                policyGroup.Name = entityGroup.Name;
                policyGroup.Description = entityGroup.Description;

                policyGroup.Policies = ListPoliciesByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return policyGroup;
        }

        public static EntityGroup GetEntityGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            EntityGroup entityGroup = new EntityGroup();
            const string sprocname = "[ServiceEngine].[GetEntityGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            entityGroup.ID = reader.GetGuid(0);
                            entityGroup.Name = reader.GetString(1);
                            if (reader.IsDBNull(2))
                            {
                                entityGroup.Description = null;
                            }
                            else
                            {
                                entityGroup.Description = reader.GetString(2);
                            }
                        }
                    }
                }               
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return entityGroup;

        }

        public static Operation GetOperation(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Operation operation = new Operation();
            const string sprocname = "[ServiceEngine].[GetOperation]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            operation.ID = reader.GetGuid(0);
                            operation.Name = reader.GetString(1);
                            if (reader.IsDBNull(2))
                            {
                                operation.Description = null;
                            }
                            else
                            {
                                operation.Description = reader.GetString(2);
                            }
                            if (reader.IsDBNull(3))
                            {
                                operation.Policy = null;
                            }
                            else
                            {
                                operation.Policy = GetPolicy(reader.GetGuid(3), txn, conn);
                            }
                        }
                    }
                }
                OperationVersionList list = ListOperationVersions(ID, txn, conn);

                if (list.OperationVersions != null)
                {
                    operation.Versions = new List<OperationVersion>();
                    foreach (OperationVersionListElement version in list.OperationVersions)
                    {
                        operation.Versions.Add(GetOperationVersion(version.ID, txn, conn));
                    }
                }
                operation.EndpointList = ListAssociatedEndpointsForOperation(ID, txn, conn);

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return operation;

        }

        private static EndpointList ListAssociatedEndpointsForOperation(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            EndpointList list = new EndpointList();
            const string sprocname = "[ServiceEngine].[ListAssociatedEndpointsForOperationID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Endpoints = new List<EndpointListElement>();
                            while (reader.Read())
                            {
                                EndpointListElement element = new EndpointListElement();
                                element.ID = reader.GetGuid(0);
                                element.URI = reader.GetString(1);
                                list.Endpoints.Add(element);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;
        }

        private static OperationVersionList ListOperationVersions(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationVersionList list = new OperationVersionList();
            const string sprocname = "[ServiceEngine].[ListOperationVersions]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.OperationVersions = new List<OperationVersionListElement>();
                            while (reader.Read())
                            {
                                OperationVersionListElement element = new OperationVersionListElement();
                                element.Version = new VersionNumber();
                                element.ID = reader.GetGuid(0);
                                VersionNumber verNumber = new VersionNumber();
                                verNumber.Major = reader.GetInt32(1).ToString();
                                verNumber.Minor = reader.GetInt32(2).ToString();
                                verNumber.Build = reader.GetInt32(3).ToString();
                                verNumber.Qfe = reader.GetInt32(4).ToString();
                                element.Version = verNumber;
                                list.OperationVersions.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static OperationVersion GetOperationVersion(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationVersion version = new OperationVersion();
            const string sprocname = "[ServiceEngine].[GetOperationVersion]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            version.ID = reader.GetGuid(0);
                            version.OperationID = reader.GetGuid(1);
                            version.OperationName = reader.GetString(2);
                            VersionNumber verNumber = new VersionNumber();
                            verNumber.Major = reader.GetInt32(3).ToString();
                            verNumber.Minor = reader.GetInt32(4).ToString();
                            verNumber.Build = reader.GetInt32(5).ToString();
                            verNumber.Qfe = reader.GetInt32(6).ToString();
                            version.Version = verNumber;
                            if (reader.IsDBNull(7))
                            {
                                version.AutoResponse = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(7).CreateReader());
                                version.AutoResponse = xdoc.DocumentElement;

                            }
                            version.IsPublic = reader.GetBoolean(8);
                            version.IsActive = reader.GetBoolean(9);
                            version.IsTestable = reader.GetBoolean(10);
                            version.RequestMsg = GetMessage(version.ID, SC.IsRequestMsg, txn, conn);
                            version.ResponseMsg = GetMessage(version.ID, SC.IsResponseMsg, txn, conn);

                            if (reader.IsDBNull(11))
                            {
                                version.RequestTransformXSLT = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(11).CreateReader());
                                version.RequestTransformXSLT = xdoc.DocumentElement;
                            }

                            if (reader.IsDBNull(12))
                            {
                                version.ResponseTransformXSLT = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(12).CreateReader());
                                version.ResponseTransformXSLT = xdoc.DocumentElement;
                            }

                            if (reader.IsDBNull(15))
                            {
                                version.Resource = null;
                            }
                            else
                            {
                                Resource res = GetResource(reader.GetGuid(15), txn, conn);
                                version.Resource = res;
                            }

                            if (reader.IsDBNull(14))
                            {
                                version.Description = null;
                            }
                            else
                            {
                                version.Description = reader.GetString(14);
                            }
                            // Get SoapFaults
                            version.SoapFaults = GetSoapFaults(ID, txn, conn);
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return version;

        }

        public static Channel GetChannel(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Channel chnl = new Channel();
            const string sprocname = "[ServiceEngine].[GetChannel]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            chnl.ID = reader.GetGuid(0);
                            chnl.Name = reader.GetString(1);
                            XmlDocument xdoc = new XmlDocument();
                            xdoc.Load(reader.GetSqlXml(2).CreateReader());
                            chnl.MonikerSchema = xdoc.DocumentElement;
                            chnl.Binding = GetMSEBinding(reader.GetGuid(3), txn, conn);
                            xdoc = new XmlDocument();

                            chnl.MonikerEditorAssemblyName = reader.GetString(4);
                            chnl.MonikerEditorTypeName = reader.GetString(5);
                            if (reader.IsDBNull(6))
                            {
                                chnl.Description = null;
                            }
                            else
                            {
                                chnl.Description = reader.GetString(6);
                            }
                        }

                        //Get policies SGK 05/06/2008
                        chnl.Policies = GetEntityPolicies(chnl.ID, txn, conn);
                    }
                }


            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return chnl;
        }

        public static List<MessagePart> GetMessage(Guid ID, bool isRequestMsg, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<MessagePart> message = new List<MessagePart>();
            const string sprocname = "[ServiceEngine].[GetMessage]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter IsRequestMsgParam = new SqlParameter("@IsRequestMsg", SqlDbType.Bit);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    IsRequestMsgParam.Value = isRequestMsg;
                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(IsRequestMsgParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                MessagePart part = new MessagePart();
                                part.ElementName = reader.GetString(2);
                                part.NamespaceURI = reader.GetString(3);
                                message.Add(part);
                            }
                        }
                    }
                }


            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return message;

        }

        public static List<SoapFault> GetSoapFaults(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<SoapFault> soapFaults = new List<SoapFault>();
            const string sprocname = "[ServiceEngine].[GetSoapFaultsForOperationVersion]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                SoapFault fault = new SoapFault();
                                fault.NamespaceURI = reader.GetString(0);
                                fault.ID = reader.GetGuid(1);
                                fault.Name = reader.GetString(2);
                                fault.Action = reader.GetString(3);
                                fault.ProtectionLevel = (System.Net.Security.ProtectionLevel)Enum.Parse(typeof(System.Net.Security.ProtectionLevel), reader.GetString(4));
                                fault.ElementName = reader.GetString(5);
                                soapFaults.Add(fault);
                            }
                        }
                    }
                }


            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return soapFaults;

        }

        public static Schema GetSchemaByNamespace(string namespaceUri, SqlTransaction txn, SqlConnection conn)
        {
            

            bool autoclose = false;
            Schema schema = null;

            try
            {
                Guid ID = GetIDFromName(namespaceUri, EntityClass.Schema,txn,conn);
                if (IsGuidNullOrEmpty(ID.ToString()) == false)
                {
                    schema = GetSchema(ID, txn, conn);
                }
                else
                {
                    throw new ApplicationException(string.Format("Schema ID is not found [{0}]", namespaceUri));
                }
            }
            catch (Exception ex)
            {
                if (autoclose) { conn.Close(); }
                throw ex;
            }

            return schema;
        }

        public static void LoadImportedSchemas(XmlSchemaSet schemaSet, Dictionary<string, string> schemaHash, XmlDocument schemaDoc,
                                                SqlTransaction txn, SqlConnection conn)
        {
            XmlNamespaceManager xmlns = new XmlNamespaceManager(schemaDoc.NameTable);
            xmlns.AddNamespace("xsd", XmlSchema.Namespace);
            XmlNodeList importNodes = schemaDoc.SelectNodes("//xsd:import", xmlns);
            foreach (XmlNode xn in importNodes)
            {
                string name = null;
                if (xn.Attributes["namespace"] != null) name = xn.Attributes["namespace"].Value;

                if (schemaHash.ContainsKey(name) == false)
                {
                    Schema schema = GetSchemaByNamespace(name, txn, conn);
                    XmlSchema xmlSchema = XmlSchema.Read(new StringReader(schema.XSD.OuterXml), null);
                    schemaSet.Add(xmlSchema);
                    schemaHash.Add(name, name);
                    XmlDocument importedSchemaDoc = new XmlDocument();
                    importedSchemaDoc.LoadXml(schema.XSD.OuterXml);

                    LoadImportedSchemas(schemaSet, schemaHash, importedSchemaDoc, txn, conn);
                }
            }

        }

        public static Boolean ValidateOperationVersionRequest(XmlElement request, Guid opVersionID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            XmlDocument tempXMLDoc = new XmlDocument();
            XmlSchemaSet schemaSet = new XmlSchemaSet();
            XmlReaderSettings settings = new XmlReaderSettings();

            XmlDocument mpSchema = new XmlDocument();
            String xsdNS;
            Dictionary<string, string> schemaHash = new Dictionary<string, string>();


            try
            {
                tempXMLDoc.LoadXml(request.OuterXml);

                OperationVersion opVer = GetOperationVersion(opVersionID, txn, conn);

                // Before we do any validation, we may want to check if 
                // the request's document element name is the same as specified in request messsage part
                // Will have to modify for multipart message
                if (opVer.RequestMsg != null && opVer.RequestMsg.Count > 0)
                {
                    if (string.Compare(request.LocalName, opVer.RequestMsg[0].ElementName, false) != 0)
                    {
                        Console.WriteLine("Request's DocumentElement name [{0}] is different from Request's Message Part Element Name [{1}]", request.LocalName, opVer.RequestMsg[0].ElementName);
                        return false;
                    }
                }
                else
                {
                    Console.WriteLine("Request's Message Part for Version [{0}] does not exist", opVer.Version.ToString());
                    return false;
                }

                foreach (MessagePart reqMP in opVer.RequestMsg)
                {
                    Schema schema = GetSchemaByNamespace(reqMP.NamespaceURI, txn, conn);
                    XmlDocument xd = new XmlDocument();
                    xd.LoadXml(schema.XSD.OuterXml);
                    if (xd != null)
                    {
                        if (schemaHash.ContainsKey(reqMP.NamespaceURI) == false)
                        {
                            XmlSchema xmlSchema = XmlSchema.Read(new StringReader(xd.OuterXml), null);
                            schemaSet.Add(xmlSchema);
                            schemaHash.Add(reqMP.NamespaceURI, reqMP.NamespaceURI);
                            LoadImportedSchemas(schemaSet, schemaHash, xd, txn, conn);
                        }
                    }
                }

                try
                {
                    schemaSet.Compile();
                }
                catch (Exception ex)
                {
                    //return false;
                    throw new ApplicationException("Failed to validate Request Message Schema due to error [" + ex.Message + "]");
                }

                try
                {
                    settings.Schemas = schemaSet;
                    settings.ConformanceLevel = ConformanceLevel.Auto;
                    settings.ValidationType = ValidationType.Schema;
                    settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
                    settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;

                    bool hasError = false;
                    // Warning validation only works if we have an event handler
                    settings.ValidationEventHandler += delegate(object sender, ValidationEventArgs e)
                    {
                        Console.WriteLine("Validation Error:[{0}]", GetExceptionDetails(e.Exception));
                        hasError = true;
                    };

                    // Create the XmlReader object.
                    XmlReader reader = XmlReader.Create(new StringReader(tempXMLDoc.OuterXml), settings);

                    // Parse the document. An XMLException should be thrown if there is an validation error
                    while (reader.Read())
                    {
                        if (hasError == true)
                            break;
                        Console.WriteLine(reader.Name + reader.NamespaceURI);
                    }
                    // This will only return true if there is no error
                    return (hasError == false);
                }

                catch (Exception ex)
                {
                    //return false;
                    throw new ApplicationException("Failed to validate Request Message due to error [" + ex.Message + "]");
                }

            }
            catch (ApplicationException aex)
            {
                if (autoclose) { conn.Close(); }
                throw aex;
            }
            catch (Exception ex)
            {
                if (autoclose) { conn.Close(); }
                return false;
            }
        }


        public static Schema GetSchema(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Schema schema = new Schema();
            XmlSchema xmlSchema = null;
            const string sprocname = "[ServiceEngine].[GetSchema]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            schema.ID = reader.GetGuid(0);
                            schema.NamespaceURI = reader.GetString(1);
                            if (reader.IsDBNull(2))
                            {
                                schema.Description = null;
                            }
                            else
                            {
                                schema.Description = reader.GetString(2);
                            }
                        }
                    }
                    xmlSchema = new XmlSchema();
                    xmlSchema.TargetNamespace = schema.NamespaceURI;
                    xmlSchema.ElementFormDefault = XmlSchemaForm.Qualified;
                }
                // Append Imports
                xmlSchema = AppendImportsToSchema(schema, xmlSchema, txn, conn);
                // Append Objects
                xmlSchema = AppendObjectsToSchema(schema, xmlSchema, txn, conn);

                XmlDocument schemaDoc = ConverXmlSchemaToDOM(xmlSchema);
                schema.XSD = schemaDoc.DocumentElement;

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return schema;
        }

        public static SchemaList ListDependencySchemas(Guid schemaID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SchemaList dependencySchemaIDs = new SchemaList();
            const string sprocname = "[ServiceEngine].[ListDependentSchemas]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = schemaID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            dependencySchemaIDs.Schemas = new List<SchemaListElement>();
                            while (reader.Read())
                            {
                                SchemaListElement schemaListElement = new SchemaListElement();

                                schemaListElement.ID = reader.GetGuid(0);
                                schemaListElement.Name = reader.GetString(1);
                                dependencySchemaIDs.Schemas.Add(schemaListElement);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return dependencySchemaIDs;
        }

        public static SchemaList ListReferencedBySchemas(Guid schemaID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SchemaList dependencySchemaIDs = new SchemaList();
            const string sprocname = "[ServiceEngine].[ListReferencedBySchemas]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = schemaID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            dependencySchemaIDs.Schemas = new List<SchemaListElement>();
                            while (reader.Read())
                            {
                                SchemaListElement schemaListElement = new SchemaListElement();

                                schemaListElement.ID = reader.GetGuid(0);
                                schemaListElement.Name = reader.GetString(1);
                                dependencySchemaIDs.Schemas.Add(schemaListElement);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return dependencySchemaIDs;
        }

        private static void BuildSchemaFromComponents()
        {
        }

        public static void DeleteSchema(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteSchema]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                // Check for any Schemas referencing this one
                SchemaList schemaList = ListReferencedBySchemas(ID, txn, conn);
                if (schemaList.Schemas != null && schemaList.Schemas.Count > 0)
                {
                    bool referencedBy = false;
                    foreach (SchemaListElement sle in schemaList.Schemas)
                    {
                        if (sle.ID != ID)
                        {
                            referencedBy = true;
                            break;
                        }
                    }
                    if (referencedBy == true)
                    {
                        throw new ApplicationException(string.Format("This schema [{0}] cannot be deleted as it is referenced by one or more schemas in the catalog", ID));
                    }
                }

                // Check for any other Entities referencing this schema
                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static List<Schema> ListSchemasForEndpoint(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<Schema> list = new List<Schema>();
            List<Guid> schemaObjectIDs = new List<Guid>();

            const string sprocname = "[ServiceEngine].[ListSchemaObjectsForEndpoint]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            HashSet<string> namespaces = new HashSet<string>();
                            while (reader.Read())
                            {
                                schemaObjectIDs.Add(reader.GetGuid(0));
                            }

                        }
                    }
                }

                if (schemaObjectIDs.Count > 0)
                {
                    Dictionary<string, XmlSchema> schemaHash = new Dictionary<string,XmlSchema>();
                    Dictionary<Guid, string> mappedTypeHash = new Dictionary<Guid, string>();

                    foreach (Guid schemaObjectID in schemaObjectIDs)
                    {
                        if (mappedTypeHash.ContainsKey(schemaObjectID) == false)
                        {
                            SchemaObject schemaObject = GetSchemaObject(schemaObjectID, txn, conn);
                            AddTypeToSchemaAndHash(schemaObject, schemaHash, mappedTypeHash);
                            AppendDependencyObjectsToSchema(schemaObject, schemaHash, mappedTypeHash);

                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;
        }

        private static void ResolveImports(XmlElement xel, HashSet<string> namespaces, SchemaList list, SqlTransaction txn, SqlConnection conn)
        {
            string impns = xel.Attributes["namespace"].Value;
            Guid impschemaid = GetIDFromName(impns, EntityClass.Schema, txn, conn);
            if (!impschemaid.Equals(Guid.Empty) && namespaces.Contains(impns) == false)
            {
                namespaces.Add(impns);
                SchemaListElement element = new SchemaListElement();
                element.ID = impschemaid;
                element.Name = impns;
                list.Schemas.Add(element);
                Schema s = GetSchema(element.ID, txn, conn);
                XmlDocument xdoc = new XmlDocument();
                xdoc.LoadXml(s.XSD.OuterXml);
                XmlNamespaceManager xmlns = new XmlNamespaceManager(xdoc.NameTable);
                xmlns.AddNamespace("xs", XmlSchema.Namespace);
                foreach (XmlElement xel2 in xdoc.SelectNodes("//xs:import", xmlns))
                {
                    ResolveImports(xel2,namespaces, list, txn, conn);
                }

            }
        }

        public static SchemaList ListSchemas(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SchemaList list = new SchemaList();
            const string sprocname = "[ServiceEngine].[ListSchemas]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Schemas = new List<SchemaListElement>();
                            while (reader.Read())
                            {
                                SchemaListElement element = new SchemaListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Schemas.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;
        }

        private static XmlDocument fixSchemaSelfReferences(XmlDocument schema, string prefix, string ns)
        {
            //TODO: Reengineer this for more robust solution

            string oldNS = string.Empty;
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(schema.NameTable);
            nsmgr.AddNamespace(SC.XsdPrefix, SC.XsdNS);
            XmlNode nsAttrInSchema = schema.SelectSingleNode("/xsd:schema/@targetNamespace", nsmgr);
            List<string> oldPrefixes = new List<string>();
            List<XmlAttribute> oldAttrs = new List<XmlAttribute>();

            if (nsAttrInSchema != null) oldNS = nsAttrInSchema.Value;
            if (!oldNS.Equals(ns))
            { // Schema has been "renamed" so let's fix this
                if (nsAttrInSchema == null)
                {
                    nsAttrInSchema = schema.CreateAttribute("targetNamespace");
                    schema.SelectSingleNode("/xsd:schema", nsmgr).Attributes.Append((XmlAttribute)nsAttrInSchema);
                }
                nsAttrInSchema.Value = ns;
                string newschema = schema.OuterXml;
                newschema.Replace(oldNS, ns);
                schema = new XmlDocument();
                schema.LoadXml(newschema);
                nsmgr = new XmlNamespaceManager(schema.NameTable);
                nsmgr.AddNamespace(SC.XsdPrefix, SC.XsdNS);
            }
            //            XmlDocument schemaElement = (XmlDocument)schema.SelectSingleNode("/xsd:schema", nsmgr);
            XmlDocument schemaElement = new XmlDocument();
            schemaElement.LoadXml(schema.SelectSingleNode("/xsd:schema", nsmgr).OuterXml);
            XmlAttribute xmlnsAttr = null;
            if (schemaElement.Attributes != null)
            {
                foreach (XmlAttribute attr in schemaElement.Attributes)
                {
                    if (attr.LocalName.Equals("xmlns"))
                    {
                        xmlnsAttr = attr;
                    }
                }
            }

            if (xmlnsAttr != null)
            { // Visual Studio has a fit if the Schema uses xmlns= to identify the types so fix this
                schemaElement.Attributes.Remove(xmlnsAttr);
                foreach (XmlNode attr in schema.SelectNodes("//@type"))
                {
                    if (!attr.Value.Contains(":"))
                    {
                        attr.Value = string.Format("{0}:{1}", prefix, attr.Value);
                    }
                }
            }

            return schema;
        }

        private static string fullSoapAction(OperationVersion version)
        {
            string response = string.Empty;

            if (version == null) throw new ArgumentNullException("version");

            if ((!string.IsNullOrEmpty(version.Version.Qfe)) && (int.Parse(version.Version.Qfe, nfi) != 0))
            {
                response = string.Format(nfi, "{0}:{1}.{2}.{3}.{4}", version.OperationName, version.Version.Major, version.Version.Minor, version.Version.Build, version.Version.Qfe);
            }
            else
            {
                if ((!string.IsNullOrEmpty(version.Version.Build)) && (int.Parse(version.Version.Build, nfi) != 0))
                {
                    response = string.Format(nfi, "{0}:{1}.{2}.{3}", version.OperationName, version.Version.Major, version.Version.Minor, version.Version.Build);
                }
                else
                {
                    response = string.Format(nfi, "{0}:{1}.{2}", version.OperationName, version.Version.Major, version.Version.Minor);
                }
            }

            return response;
        }

        public static Schema UpdateSchema(Schema schema, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateSchema]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = new List<DBEventDataItem>();
                try
                {
                    OperationVersionList opVerList = DAL.ListOperationVersionsBySchema(schema.ID, txn, conn);
                    if (opVerList != null && opVerList.OperationVersions != null)
                    {
                        foreach (OperationVersionListElement element in opVerList.OperationVersions)
                        {
                            List<DBEventDataItem> temp = DAL.ListRuntimeServersForOperationVersionID(element.ID, txn, conn);
                            temp.ForEach(item => { if (!eventData.Contains(item)) eventData.Add(item); });
                        }
                    }
                    
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in UpdateSchema.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }
                #endregion

                // Update Schema Objects
                CreateSchemaObjects(schema, txn, conn);

                // Update Schema Imports
                if (schema.ImportedSchemas != null && schema.ImportedSchemas.Count > 0)
                {
                    DeleteSchemaImport(schema.ID, txn, conn);
                    foreach (SchemaImport schemaImport in schema.ImportedSchemas)
                    {
                        UpdateSchemaImport(schema.ID, schemaImport, txn, conn);
                    }
                }

                //send notification to affected runtimes
                RepositoryChangeManager.RecordChange(DBEvents.OperationsUpdated, DBChangeType.Update, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return schema;
        }

        public static List<OperationListElement> ListOperationsByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<OperationListElement> list = new List<OperationListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<OperationListElement>();
                            while (reader.Read())
                            {
                                OperationListElement element = new OperationListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<EndpointListElement> ListEndpointsByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<EndpointListElement> list = new List<EndpointListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<EndpointListElement>();
                            while (reader.Read())
                            {
                                EndpointListElement element = new EndpointListElement();
                                element.ID = reader.GetGuid(0);
                                element.URI = reader.GetString(1);                            
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<SchemaListElement> ListSchemasByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<SchemaListElement> list = new List<SchemaListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<SchemaListElement>();
                            while (reader.Read())
                            {
                                SchemaListElement element = new SchemaListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<RuntimeServerListElement> ListRuntimeServersByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<RuntimeServerListElement> list = new List<RuntimeServerListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<RuntimeServerListElement>();
                            while (reader.Read())
                            {
                                RuntimeServerListElement element = new RuntimeServerListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<ChannelListElement> ListChannelsByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<ChannelListElement> list = new List<ChannelListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<ChannelListElement>();
                            while (reader.Read())
                            {
                                ChannelListElement element = new ChannelListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }
        
        public static List<PolicyListElement> ListPoliciesByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<PolicyListElement> list = new List<PolicyListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<PolicyListElement>();
                            while (reader.Read())
                            {
                                PolicyListElement element = new PolicyListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static OperationList ListOperationsByElement(Guid SchemaID, string elementName, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationList list = new OperationList();
            const string sprocname = "[ServiceEngine].[ListOperationsByElement]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@ElementName", SqlDbType.NVarChar, 400);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = SchemaID;
                    cmd.Parameters.Add(IDParam);
                    NameParam.Value = elementName;
                    cmd.Parameters.Add(NameParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Operations = new List<OperationListElement>();
                            while (reader.Read())
                            {
                                OperationListElement element = new OperationListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Operations.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static OperationList ListOperationsBySchema(Guid SchemaID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationList list = new OperationList();
            const string sprocname = "[ServiceEngine].[ListOperationsBySchema]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = SchemaID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Operations = new List<OperationListElement>();
                            while (reader.Read())
                            {
                                OperationListElement element = new OperationListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Operations.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static OperationVersionList ListOperationVersionsBySchema(Guid SchemaID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationVersionList list = new OperationVersionList();
            const string sprocname = "[ServiceEngine].[ListOperationVersionsBySchema]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = SchemaID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.OperationVersions = new List<OperationVersionListElement>();
                            while (reader.Read())
                            {
                                OperationVersionListElement element = new OperationVersionListElement();
                                element.Version = new VersionNumber();
                                element.ID = reader.GetGuid(0);
                                VersionNumber verNumber = new VersionNumber();
                                verNumber.Major = reader.GetInt32(1).ToString();
                                verNumber.Minor = reader.GetInt32(2).ToString();
                                verNumber.Build = reader.GetInt32(3).ToString();
                                verNumber.Qfe = reader.GetInt32(4).ToString();
                                element.Version = verNumber;
                                list.OperationVersions.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static OperationVersionList ListOperationVersionsForResource(Guid ResourceID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationVersionList list = new OperationVersionList();
            const string sprocname = "[ServiceEngine].[ListOperationVersionsByResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ResourceID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ResourceID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.OperationVersions = new List<OperationVersionListElement>();
                            while (reader.Read())
                            {
                                OperationVersionListElement element = new OperationVersionListElement();
                                element.Version = new VersionNumber();
                                element.ID = reader.GetGuid(0);
                                VersionNumber verNumber = new VersionNumber();
                                verNumber.Major = reader.GetInt32(1).ToString();
                                verNumber.Minor = reader.GetInt32(2).ToString();
                                verNumber.Build = reader.GetInt32(3).ToString();
                                verNumber.Qfe = reader.GetInt32(4).ToString();
                                element.Version = verNumber;
                                list.OperationVersions.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static OperationList ListOperationsByFirstElement(Guid SchemaID, string elementName, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationList list = new OperationList();
            const string sprocname = "[ServiceEngine].[ListOperationsByFirstElement]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@ElementName", SqlDbType.NVarChar, 400);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = SchemaID;
                    cmd.Parameters.Add(IDParam);
                    NameParam.Value = elementName;
                    cmd.Parameters.Add(NameParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Operations = new List<OperationListElement>();
                            while (reader.Read())
                            {
                                OperationListElement element = new OperationListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Operations.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static Guid CreateSchema(Schema schema, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }
                
                CreateSchemaNamespace(schema, txn, conn);

                CreateSchemaObjects(schema, txn, conn);

                if (schema.ImportedSchemas != null && schema.ImportedSchemas.Count > 0)
                {
                    foreach (SchemaImport import in schema.ImportedSchemas)
                    {
                        CreateSchemaImport(schema.ID, import, txn, conn);
                    }
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return schema.ID;
        }

        private static void CreateSchemaObjects(Schema schema, SqlTransaction txn, SqlConnection conn)
        {
            try 
            {
                bool autoclose = false;

                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                Dictionary<string, Guid> mappedElemntHash = new Dictionary<string, Guid>();
                Dictionary<string, Guid> schemaHash = new Dictionary<string, Guid>();
                List<Guid> schemaIDs = new List<Guid>();
                XmlSchemaSet xssImport = new XmlSchemaSet();

                XmlSchema xs = null;
                if (schema.Objects != null && schema.Objects.Count > 0)
                    xs = CreateXmlSchemaFromSchema(schema, false);
                else
                    xs = LoadXmlSchemaFromString(schema.XSD.OuterXml);
                xssImport.Add(xs);
                CollectRealatedSchemas(schema,schemaHash,schemaIDs,xssImport,txn,conn);

                CreateSchemaObjectsFromXmlSchema(xssImport, xs, mappedElemntHash, schemaHash, txn, conn);
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("An error occurred while creating schema Objects for Schema [{0}]", schema.NamespaceURI),ex);
            }
        }
        
        private static void CreateSchemaObjectsFromXmlSchema(XmlSchemaSet xssImport, XmlSchema xs, Dictionary<string, Guid> mappedElemntHash,
                                                             Dictionary<string, Guid> schemaHash, SqlTransaction txn, SqlConnection conn)
        {
            // Now Save Schema Elements
            foreach (XmlSchemaObject xso in xs.Attributes.Values)
            {
                XmlSchemaAttribute xsa = (XmlSchemaAttribute)xso;
                CollectSchemaTypes(xssImport, xsa.QualifiedName, xsa, true, SchemaObjectType.Attribute, schemaHash, mappedElemntHash, Guid.Empty, txn, conn);
            }
            foreach (XmlSchemaObject xso in xs.AttributeGroups.Values)
            {
                XmlSchemaAttributeGroup xsag = (XmlSchemaAttributeGroup)xso;
                CollectSchemaTypes(xssImport, xsag.QualifiedName, xsag, true, SchemaObjectType.AttributeGroup, schemaHash, mappedElemntHash, Guid.Empty, txn, conn);
            }
            foreach (XmlSchemaObject xso in xs.SchemaTypes.Values)
            {
                XmlSchemaType xst = (XmlSchemaType)xso;
                CollectSchemaTypes(xssImport, xst.QualifiedName, xst, true, GetSchemaObjectType(xso), schemaHash, mappedElemntHash, Guid.Empty, txn, conn);
            }
            foreach (XmlSchemaObject xso in xs.Elements.Values)
            {
                XmlSchemaElement xse = (XmlSchemaElement)xso;
                CollectSchemaTypes(xssImport, xse.QualifiedName, xse, true, SchemaObjectType.Element, schemaHash, mappedElemntHash, Guid.Empty, txn, conn);
            }
        }
        private static Guid CreateSchemaNamespace(Schema schema, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateSchema]";
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }
                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = schema.NamespaceURI;
                    DescriptionParam.Value = schema.Description;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();
                    schema.ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();

                return schema.ID;
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("An error occurred while creating namespace for Schema [{0}]", schema.NamespaceURI),ex);
            }
        }

        public static Guid CreateSchemaObject(SchemaObject schemaObject, Guid parentID, Guid schemaID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateSchemaObject]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter SchemaIDParam = new SqlParameter("@schemaID", SqlDbType.UniqueIdentifier);
                    SqlParameter SchemaObjectTypeParam = new SqlParameter("@schemaObjectType", SqlDbType.SmallInt);
                    SqlParameter SchemaObjectNameParam = new SqlParameter("@schemaObjectName", SqlDbType.NVarChar, 256);
                    SqlParameter SchemaObjectXmlParam = new SqlParameter("@schemaObjectXml", SqlDbType.Xml);
                    SqlParameter ParentIDParam = new SqlParameter("@parentID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;

                    IDParam.Direction = ParameterDirection.Output;
                    SchemaIDParam.Value = schemaID;
                    SchemaObjectTypeParam.Value = Convert.ToInt16(schemaObject.Type);
                    SchemaObjectNameParam.Value = schemaObject.Name;
                    SchemaObjectXmlParam.Value = schemaObject.Xml.OuterXml;
                    if (parentID == Guid.Empty)
                        ParentIDParam.Value = null;
                    else
                        ParentIDParam.Value = parentID;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(SchemaIDParam);
                    cmd.Parameters.Add(SchemaObjectTypeParam);
                    cmd.Parameters.Add(SchemaObjectXmlParam);
                    cmd.Parameters.Add(SchemaObjectNameParam);
                    cmd.Parameters.Add(ParentIDParam);

                    cmd.ExecuteNonQuery();
                    schemaObject.ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return schemaObject.ID;
        }

        private static Guid CreateSchemaObjectDependency(Guid SchemaObjectID, Guid parentID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateSchemaObjectDependency]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter SchemaObjectIDParam = new SqlParameter("@SchemaObjectID", SqlDbType.UniqueIdentifier);
                    SqlParameter ParentIDParam = new SqlParameter("@ParentObjectID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;

                    IDParam.Direction = ParameterDirection.Output;
                    SchemaObjectIDParam.Value = SchemaObjectID;
                    ParentIDParam.Value = parentID;

                    cmd.Parameters.Add(SchemaObjectIDParam);
                    cmd.Parameters.Add(ParentIDParam);
                    cmd.Parameters.Add(IDParam);
                    cmd.ExecuteNonQuery();
                    return (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static Guid UpdateSchemaObject(SchemaObject schemaObject, Guid existingSchemaObjectID, Guid parentID, Guid schemaID, 
                                                SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateSchemaObject]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter SchemaObjectIDParam = new SqlParameter("@schemaObjectID", SqlDbType.UniqueIdentifier);
                    SqlParameter SchemaIDParam = new SqlParameter("@schemaID", SqlDbType.UniqueIdentifier);
                    SqlParameter SchemaObjectTypeParam = new SqlParameter("@schemaObjectType", SqlDbType.SmallInt);
                    SqlParameter SchemaObjectNameParam = new SqlParameter("@schemaObjectName", SqlDbType.NVarChar, 256);
                    SqlParameter SchemaObjectXmlParam = new SqlParameter("@schemaObjectXml", SqlDbType.Xml);
                    SqlParameter ParentIDParam = new SqlParameter("@parentID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;

                    IDParam.Direction = ParameterDirection.Output;
                    SchemaObjectIDParam.Value = existingSchemaObjectID;
                    SchemaIDParam.Value = schemaID;
                    SchemaObjectTypeParam.Value = Convert.ToInt16(schemaObject.Type);
                    SchemaObjectNameParam.Value = schemaObject.Name;
                    SchemaObjectXmlParam.Value = schemaObject.Xml.OuterXml;
                    ParentIDParam.Value = parentID;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(SchemaObjectIDParam);
                    cmd.Parameters.Add(SchemaIDParam);
                    cmd.Parameters.Add(SchemaObjectTypeParam);
                    cmd.Parameters.Add(SchemaObjectXmlParam);
                    cmd.Parameters.Add(SchemaObjectNameParam);
                    if (parentID == Guid.Empty)
                        ParentIDParam.Value = null;
                    else
                        ParentIDParam.Value = parentID;

                    cmd.ExecuteNonQuery();
                    schemaObject.ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return schemaObject.ID;
        }

        private static Guid CreateSchemaImport(Guid schemaID, SchemaImport import, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateSchemaImport]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter SchemaIDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@ImportNamespace", SqlDbType.NVarChar, 256);
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = import.NamespaceURI;
                    SchemaIDParam.Value = schemaID;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(SchemaIDParam);

                    cmd.ExecuteNonQuery();
                    import.ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return import.ID;
        }

        private static void UpdateSchemaImport(Guid schemaID, SchemaImport import, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateSchemaImport]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter SchemaImportID = new SqlParameter("@SchemaImportID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@ImportNamespace", SqlDbType.NVarChar, 256);

                    cmd.CommandType = CommandType.StoredProcedure;
                    NameParam.Value = import.NamespaceURI;
                    SchemaImportID.Value = import.ID;

                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(SchemaImportID);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        private static void DeleteSchemaImport(Guid schemaID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteSchemaImport]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter SchemaID = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    SchemaID.Value = schemaID;

                    cmd.Parameters.Add(SchemaID);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static bool EntityExists(Guid entityID, EntityClass entityClass, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            bool exists;
            const string sprocname = "[ServiceEngine].[EntityExists]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter entityIDParam = new SqlParameter("@EntityID", SqlDbType.UniqueIdentifier);
                    SqlParameter entityTypeIDParam = new SqlParameter("@EntityTypeID", SqlDbType.Int);
                    SqlParameter entityExistsParam = new SqlParameter("@EntityExists", SqlDbType.Bit);

                    cmd.CommandType = CommandType.StoredProcedure;
                    entityIDParam.Value = entityID;
                    entityExistsParam.Direction = ParameterDirection.Output;
                    entityTypeIDParam.Value = (int)entityClass;
                    cmd.Parameters.Add(entityExistsParam);
                    cmd.Parameters.Add(entityTypeIDParam);
                    cmd.Parameters.Add(entityIDParam);

                    cmd.ExecuteNonQuery();

                    exists = (bool)entityExistsParam.Value;
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return exists;
        }

        public static OperationGroup CreateOperationGroup(OperationGroup operationGroup, SqlTransaction txn, SqlConnection conn)
        {
            operationGroup.ID = CreateEntityGroup(operationGroup.Name, operationGroup.Description, 4, txn, conn);

            if (operationGroup.Operations != null)
            {
                foreach (OperationListElement operation in operationGroup.Operations)
                {
                    AssignEntityToEntityGroup(operationGroup.ID, operation.ID, txn, conn);
                }
            }

            return operationGroup;
        }

        public static EndpointGroup CreateEndpointGroup(EndpointGroup endpointGroup, SqlTransaction txn, SqlConnection conn)
        {
            
            bool autoclose = false;                     

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            endpointGroup.ID = CreateEntityGroup(endpointGroup.Name, endpointGroup.Description, 2, txn, conn);

            if (endpointGroup.Endpoints != null)
            {
                foreach (EndpointListElement endpoint in endpointGroup.Endpoints)
                {
                    AssignEntityToEntityGroup(endpointGroup.ID, endpoint.ID, txn, conn);
                }
            }

            if ((autoclose) && (txn != null)) txn.Commit();

            return endpointGroup;
        }

        public static SchemaGroup CreateSchemaGroup(SchemaGroup schemaGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            schemaGroup.ID = CreateEntityGroup(schemaGroup.Name, schemaGroup.Description, 9, txn, conn);

            if (schemaGroup.Schemas != null)
            {
                foreach (SchemaListElement schema in schemaGroup.Schemas)
                {
                    AssignEntityToEntityGroup(schemaGroup.ID, schema.ID, txn, conn);
                }
            }

            if ((autoclose) && (txn != null)) txn.Commit();

            return schemaGroup;
        }

        public static RuntimeServerGroup CreateRuntimeServerGroup(RuntimeServerGroup runtimeServerGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            runtimeServerGroup.ID = CreateEntityGroup(runtimeServerGroup.Name, runtimeServerGroup.Description, 0, txn, conn);

            if (runtimeServerGroup.RuntimeServers != null)
            {
                foreach (RuntimeServerListElement runtimeServer in runtimeServerGroup.RuntimeServers)
                {
                    AssignEntityToEntityGroup(runtimeServerGroup.ID, runtimeServer.ID, txn, conn);
                }
            }

            if ((autoclose) && (txn != null)) txn.Commit();

            return runtimeServerGroup;
        }

        public static ChannelGroup CreateChannelGroup(ChannelGroup channelGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            channelGroup.ID = CreateEntityGroup(channelGroup.Name, channelGroup.Description, 7, txn, conn);

            if (channelGroup.Channels != null)
            {
                foreach (ChannelListElement channel in channelGroup.Channels)
                {
                    AssignEntityToEntityGroup(channelGroup.ID, channel.ID, txn, conn);
                }
            }

            if ((autoclose) && (txn != null)) txn.Commit();

            return channelGroup;
        }
        
        public static PolicyGroup CreatePolicyGroup(PolicyGroup policyGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            policyGroup.ID = CreateEntityGroup(policyGroup.Name, policyGroup.Description, 8, txn, conn);

            if (policyGroup.Policies != null)
            {
                foreach (PolicyListElement policy in policyGroup.Policies)
                {
                    AssignEntityToEntityGroup(policyGroup.ID, policy.ID, txn, conn);
                }
            }

            if ((autoclose) && (txn != null)) txn.Commit();

            return policyGroup;
        }

        public static Guid CreateEntityGroup(string groupName, string groupDesc, Int16 entityTypeID, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateEntityGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);
                
                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter EntityTypeParam = new SqlParameter("@EntityTypeID", SqlDbType.SmallInt);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = groupName;
                    DescriptionParam.Value = groupDesc;
                    EntityTypeParam.Value = entityTypeID;


                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(EntityTypeParam);

                    cmd.ExecuteNonQuery();

                    ID = (Guid)IDParam.Value;                    

                }
                if ((autoclose) && (txn != null)) txn.Commit();              
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static void AssignEntityToEntityGroup(Guid entityGroupID, Guid entityID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[AssignEntityToEntityGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter EntityGroupIDParam = new SqlParameter("@EntityGroupID", SqlDbType.UniqueIdentifier);
                    SqlParameter EntityIDParam = new SqlParameter("@EntityID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    EntityGroupIDParam.Value = entityGroupID;
                    cmd.Parameters.Add(EntityGroupIDParam);
                    EntityIDParam.Value = entityID;
                    cmd.Parameters.Add(EntityIDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void RemoveEntityFromEntityGroup(Guid entityGroupID, Guid entityID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[RemoveEntityFromEntityGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter EntityGroupIDParam = new SqlParameter("@EntityGroupID", SqlDbType.UniqueIdentifier);
                    SqlParameter EntityIDParam = new SqlParameter("@EntityID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    EntityGroupIDParam.Value = entityGroupID;
                    cmd.Parameters.Add(EntityGroupIDParam);
                    EntityIDParam.Value = entityID;
                    cmd.Parameters.Add(EntityIDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static Guid CreateOperation(Operation operation, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            Guid policyID = Guid.Empty;
            Guid implementationID = Guid.Empty;
            int sequenceNumber = 0;
            const string sprocname = "[ServiceEngine].[CreateOperation]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                if (operation.Policy != null)
                {
                    if ((operation.Policy.ID == null) || (!EntityExists(operation.Policy.ID, EntityClass.Policy, txn, conn)))
                    {
                        policyID = CreatePolicy(operation.Policy, txn, conn);
                    }
                    else
                    {
                        policyID = operation.Policy.ID;
                    }
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = operation.Name;
                    DescriptionParam.Value = operation.Description;

                    if (policyID.Equals(Guid.Empty))
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }
                    else
                    {
                        PolicyIDParam.Value = policyID;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(PolicyIDParam);

                    cmd.ExecuteNonQuery();

                    ID = (Guid)IDParam.Value;

                    operation.ID = ID;
                }

                if (operation.Versions != null)
                {
                    foreach (OperationVersion version in operation.Versions)
                    {
                        version.OperationID = operation.ID;
                        CreateOperationVersion(version, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static Guid CreateOperationVersion(OperationVersion version, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            Guid implementationID = Guid.Empty;
            const string sprocname = "[ServiceEngine].[CreateOperationVersion]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter OperationIDParam = new SqlParameter("@OperationID", SqlDbType.UniqueIdentifier);
                    SqlParameter VersionMajorParam = new SqlParameter("@VersionMajor", SqlDbType.Int);
                    SqlParameter VersionMinorParam = new SqlParameter("@VersionMinor", SqlDbType.Int);
                    SqlParameter VersionBuildParam = new SqlParameter("@VersionBuild", SqlDbType.Int);
                    SqlParameter VersionQFEParam = new SqlParameter("@VersionQFE", SqlDbType.Int);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter AutoResponseParam = new SqlParameter("@AutoResponse", SqlDbType.Xml);
                    SqlParameter IsPublicParam = new SqlParameter("@IsPublic", SqlDbType.Bit);
                    SqlParameter IsActiveParam = new SqlParameter("@IsActive", SqlDbType.Bit);
                    SqlParameter IsTestableParam = new SqlParameter("@IsTestable", SqlDbType.Bit);
                    SqlParameter RequestTransformParam = new SqlParameter("@RequestTransform", SqlDbType.Xml);
                    SqlParameter ResponseTransformParam = new SqlParameter("@ResponseTransform", SqlDbType.Xml);
                    SqlParameter ResourceIDParam = new SqlParameter("@ResourceID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    OperationIDParam.Value = version.OperationID;
                    VersionMajorParam.Value = int.Parse(version.Version.Major);
                    VersionMinorParam.Value = int.Parse(version.Version.Minor);
                    VersionBuildParam.Value = int.Parse(version.Version.Build);
                    VersionQFEParam.Value = int.Parse(version.Version.Qfe);
                    DescriptionParam.Value = version.Description;
                    if (version.AutoResponse != null)
                    {
                        AutoResponseParam.Value = version.AutoResponse.OuterXml;
                    }
                    else
                    {
                        AutoResponseParam.Value = DBNull.Value;
                    }
                    IsPublicParam.Value = version.IsPublic;
                    IsActiveParam.Value = version.IsActive;
                    IsTestableParam.Value = version.IsTestable;
                    if (version.RequestTransformXSLT != null)
                    {
                        RequestTransformParam.Value = version.RequestTransformXSLT.OuterXml;
                    }
                    else
                    {
                        RequestTransformParam.Value = DBNull.Value;
                    }
                    if (version.ResponseTransformXSLT != null)
                    {
                        ResponseTransformParam.Value = version.ResponseTransformXSLT.OuterXml;
                    }
                    else
                    {
                        ResponseTransformParam.Value = DBNull.Value;
                    }
                    if (version.Resource != null)
                    {
                        if (version.Resource.ID.Equals(Guid.Empty))
                        {
                            ResourceIDParam.Value = CreateResource(version.Resource, txn, conn);
                        }
                        else
                        {
                            ResourceIDParam.Value = version.Resource.ID;
                        }
                    }
                    else
                    {
                        ResourceIDParam.Value = null;
                        //throw new ApplicationException("CreateOperationVersion requires ChannelType, but no ChannelType was supplied");
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(OperationIDParam);
                    cmd.Parameters.Add(VersionMajorParam);
                    cmd.Parameters.Add(VersionMinorParam);
                    cmd.Parameters.Add(VersionBuildParam);
                    cmd.Parameters.Add(VersionQFEParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(AutoResponseParam);
                    cmd.Parameters.Add(IsPublicParam);
                    cmd.Parameters.Add(IsActiveParam);
                    cmd.Parameters.Add(IsTestableParam);
                    cmd.Parameters.Add(RequestTransformParam);
                    cmd.Parameters.Add(ResponseTransformParam);
                    cmd.Parameters.Add(ResourceIDParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                }

                int partNo = 0;

                if (version.RequestMsg != null)
                {
                    foreach (MessagePart part in version.RequestMsg)
                    {
                        CreateMessagePart(part, ID, partNo++, SC.IsRequestMsg, txn, conn);
                    }
                }

                if (version.ResponseMsg != null)
                {
                    partNo = 0;
                    foreach (MessagePart part in version.ResponseMsg)
                    {
                        CreateMessagePart(part, ID, partNo++, SC.IsResponseMsg, txn, conn);
                    }
                }
                // Create Soap Faults
                if (version.SoapFaults != null && version.SoapFaults.Count > 0)
                {
                    partNo = 0;
                    foreach (SoapFault fault in version.SoapFaults)
                    {
                        CreateSoapFault(fault, ID, txn, conn);
                    }
                }
                
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        private static void CreateMessagePart(MessagePart part, Guid operationVersionID, int ordinal, bool isRequestMsg, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateMessagePart]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                SchemaObject schemaObject = GetSchemaObjectByNameTypeAndNamespace(part.NamespaceURI, part.ElementName, SchemaObjectType.Element, txn, conn);

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter OperationVersionIDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter IsRequestMsgParam = new SqlParameter("@IsRequestMsg", SqlDbType.Bit);
                    SqlParameter OrdinalParam = new SqlParameter("@Ordinal", SqlDbType.Int);
                    SqlParameter SchemaObjectIDParam = new SqlParameter("@SchemaObjectID", SqlDbType.UniqueIdentifier);


                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    
                    OperationVersionIDParam.Value = operationVersionID;
                    SchemaObjectIDParam.Value = schemaObject.ID;
                    OrdinalParam.Value = ordinal;
                    IsRequestMsgParam.Value = isRequestMsg;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(OperationVersionIDParam);
                    cmd.Parameters.Add(SchemaObjectIDParam);
                    cmd.Parameters.Add(OrdinalParam);
                    cmd.Parameters.Add(IsRequestMsgParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        private static void CreateSoapFault(SoapFault fault, Guid operationVersionID, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateSoapFaultForOperationVersion]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                SchemaObject schemaObject = GetSchemaObjectByNameTypeAndNamespace(fault.NamespaceURI, fault.ElementName, SchemaObjectType.Element, txn, conn);

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter OperationVersionIDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter ActionParam = new SqlParameter("@Action", SqlDbType.NVarChar, 256);
                    SqlParameter ProtectionLevelParam = new SqlParameter("@ProtectionLevel", SqlDbType.NVarChar, 32);
                    SqlParameter SchemaObjectIDParam = new SqlParameter("@SchemaObjectID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;

                    OperationVersionIDParam.Value = operationVersionID;
                    NameParam.Value = fault.Name;
                    SchemaObjectIDParam.Value = schemaObject.ID;
                    ActionParam.Value = fault.Action;
                    ProtectionLevelParam.Value = fault.ProtectionLevel.ToString();

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(OperationVersionIDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(SchemaObjectIDParam);
                    cmd.Parameters.Add(ActionParam);
                    cmd.Parameters.Add(ProtectionLevelParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                    fault.ID = ID;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static OperationGroupList ListOperationGroupsByOperation(Guid entityID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationGroupList list = new OperationGroupList();
            const string sprocname = "[ServiceEngine].[ListEntityGroupsByEntity]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityID", SqlDbType.UniqueIdentifier);
                    IDParam.Value = entityID;
                    cmd.Parameters.Add(IDParam);

                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.OperationGroups = new List<OperationGroupListElement>();
                            while (reader.Read())
                            {
                                OperationGroupListElement element = new OperationGroupListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.OperationGroups.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;
        }

        public static OperationGroupList ListOperationGroups(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationGroupList list = new OperationGroupList();
            const string sprocname = "[ServiceEngine].[ListEntityGroups]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityTypeID", SqlDbType.SmallInt);
                    IDParam.Value = 4;
                    cmd.Parameters.Add(IDParam);

                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.OperationGroups = new List<OperationGroupListElement>();
                            while (reader.Read())
                            {
                                OperationGroupListElement element = new OperationGroupListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.OperationGroups.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;
        }

        public static EntityGroupList ListEntityGroups(Int16 entityTypeID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            EntityGroupList list = new EntityGroupList();
            const string sprocname = "[ServiceEngine].[ListEntityGroups]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityTypeID", SqlDbType.SmallInt);
                    IDParam.Value = entityTypeID;
                    cmd.Parameters.Add(IDParam);

                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.EntityGroups = new List<EntityGroupListElement>();
                            while (reader.Read())
                            {
                                EntityGroupListElement element = new EntityGroupListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.EntityGroups.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;
        }

        public static EntityGroupList ListEntityGroupsByEntity(Guid entityID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            EntityGroupList list = new EntityGroupList();
            const string sprocname = "[ServiceEngine].[ListEntityGroupsByEntity]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityID", SqlDbType.UniqueIdentifier);
                    IDParam.Value = entityID;
                    cmd.Parameters.Add(IDParam);

                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.EntityGroups = new List<EntityGroupListElement>();
                            while (reader.Read())
                            {
                                EntityGroupListElement element = new EntityGroupListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.EntityGroups.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;
        }

        public static OperationList ListOperations(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            OperationList list = new OperationList();
            const string sprocname = "[ServiceEngine].[ListOperations]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {

                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Operations = new List<OperationListElement>();
                            while (reader.Read())
                            {
                                OperationListElement element = new OperationListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Operations.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static void DeleteEntityGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteEntityGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;

                    NameParam.Direction = ParameterDirection.Output;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);

                    cmd.ExecuteNonQuery();

                    string operationGroupName = (string)NameParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void DeleteOperation(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteOperation]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }


                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;

                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void DeleteOperationVersion(Guid ID, SqlTransaction txn, SqlConnection conn, bool trackChanges)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteOperationVersion]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                try
                {
                    if (trackChanges)
                    {
                        eventData = DAL.ListRuntimeServersForOperationVersionID(ID, txn, conn);
                    }
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in DeleteOperationVersion.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                // Delete all Soap Faults associations for this version
                DeleteSoapFaults(ID, txn, conn);

                //send notification to affected runtimes
                if (trackChanges)
                {
                    RepositoryChangeManager.RecordChange(DBEvents.OperationsUpdated, DBChangeType.Delete, eventData, txn, conn);
                }

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static OperationGroup UpdateOperationGroup(OperationGroup operationGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(operationGroup.ID, operationGroup.Name, operationGroup.Description, txn, conn);


                List<OperationListElement> oldList = ListOperationsByGroup(operationGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (OperationListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(operationGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (operationGroup.Operations != null)
                {
                    foreach (OperationListElement newListElement in operationGroup.Operations)
                    {
                        AssignEntityToEntityGroup(operationGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return operationGroup;
        }

        public static EndpointGroup UpdateEndpointGroup(EndpointGroup endpointGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(endpointGroup.ID, endpointGroup.Name, endpointGroup.Description, txn, conn);


                List<EndpointListElement> oldList = ListEndpointsByGroup(endpointGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (EndpointListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(endpointGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (endpointGroup.Endpoints != null)
                {
                    foreach (EndpointListElement newListElement in endpointGroup.Endpoints)
                    {
                        AssignEntityToEntityGroup(endpointGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return endpointGroup;
        }

        public static SchemaGroup UpdateSchemaGroup(SchemaGroup schemaGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(schemaGroup.ID, schemaGroup.Name, schemaGroup.Description, txn, conn);


                List<SchemaListElement> oldList = ListSchemasByGroup(schemaGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (SchemaListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(schemaGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (schemaGroup.Schemas != null)
                {
                    foreach (SchemaListElement newListElement in schemaGroup.Schemas)
                    {
                        AssignEntityToEntityGroup(schemaGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return schemaGroup;
        }

        public static RuntimeServerGroup UpdateRuntimeServerGroup(RuntimeServerGroup runtimeServerGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(runtimeServerGroup.ID, runtimeServerGroup.Name, runtimeServerGroup.Description, txn, conn);


                List<RuntimeServerListElement> oldList = ListRuntimeServersByGroup(runtimeServerGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (RuntimeServerListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(runtimeServerGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (runtimeServerGroup.RuntimeServers != null)
                {
                    foreach (RuntimeServerListElement newListElement in runtimeServerGroup.RuntimeServers)
                    {
                        AssignEntityToEntityGroup(runtimeServerGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return runtimeServerGroup;
        }

        public static ChannelGroup UpdateChannelGroup(ChannelGroup channelGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(channelGroup.ID, channelGroup.Name, channelGroup.Description, txn, conn);


                List<ChannelListElement> oldList = ListChannelsByGroup(channelGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (ChannelListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(channelGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (channelGroup.Channels != null)
                {
                    foreach (ChannelListElement newListElement in channelGroup.Channels)
                    {
                        AssignEntityToEntityGroup(channelGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return channelGroup;
        }
        
        public static PolicyGroup UpdatePolicyGroup(PolicyGroup policyGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(policyGroup.ID, policyGroup.Name, policyGroup.Description, txn, conn);

                List<PolicyListElement> oldList = ListPoliciesByGroup(policyGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (PolicyListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(policyGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (policyGroup.Policies != null)
                {
                    foreach (PolicyListElement newListElement in policyGroup.Policies)
                    {
                        AssignEntityToEntityGroup(policyGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return policyGroup;
        }

        public static Guid UpdateEntityGroup(Guid groupID, string groupName, string groupDesc, SqlTransaction txn, SqlConnection conn)
        {            
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateEntityGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;

                    IDParam.Value = groupID;
                    NameParam.Value = groupName;
                    DescriptionParam.Value = groupDesc;


                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();
                }
                //get existing versions

                
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return groupID;
        }

        public static Operation UpdateOperation(Operation operation, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateOperation]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                try
                {
                    eventData = DAL.ListRuntimeServersForOperationID(operation.ID, txn, conn);
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in UpdateOperation.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;

                    IDParam.Value = operation.ID;
                    NameParam.Value = operation.Name;
                    DescriptionParam.Value = operation.Description;

                    if (operation.Policy == null)
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }
                    else
                    {
                        PolicyIDParam.Value = operation.Policy.ID;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(PolicyIDParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;

                }
                //get existing versions

                OperationVersionList list = ListOperationVersions(ID, txn, conn);

                //Note: there is no need to track changes at the op version level
                //this method will raise the event at operation level which is coarser grained
                if (list.OperationVersions != null)
                {
                    bool present = false;
                    if (list.OperationVersions.Count > operation.Versions.Count)
                    {
                        foreach (OperationVersionListElement version in list.OperationVersions)
                        {
                            present = false;
                            foreach (OperationVersion xversion in operation.Versions)
                            {
                                if (version.ID == xversion.ID)
                                    present = true;
                            }
                            if (!present)
                                DeleteOperationVersion(version.ID, txn, conn, false); 


                        }
                    }
                    foreach (OperationVersion xversion in operation.Versions)
                    {
                        present = false;
                        foreach (OperationVersionListElement version in list.OperationVersions)
                        {
                            if (version.ID == xversion.ID)
                            {
                                //no need to track changes at the version level since we will raise the event at operation level
                                UpdateOperationVersion(xversion, txn, conn, false);
                                present = true;
                                break;
                            }
                        }
                        if (!present)
                            CreateOperationVersion(xversion, txn, conn);
                    }

                }

                //send notification to affected runtimes
                RepositoryChangeManager.RecordChange(DBEvents.OperationsUpdated, DBChangeType.Update, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return operation;
        }

        public static OperationVersion UpdateOperationVersion(OperationVersion operationVersion, SqlTransaction txn, SqlConnection conn, bool trackChanges)
        {
            Guid ID;
            Guid policyID = Guid.Empty;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateOperationVersion]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                try
                {
                    if (trackChanges)
                    {
                        eventData = DAL.ListRuntimeServersForOperationVersionID(operationVersion.ID, txn, conn);
                    }
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in UpdateOperationVersion.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter VersionMajorParam = new SqlParameter("@VersionMajor", SqlDbType.Int);
                    SqlParameter VersionMinorParam = new SqlParameter("@VersionMinor", SqlDbType.Int);
                    SqlParameter VersionBuildParam = new SqlParameter("@VersionBuild", SqlDbType.Int);
                    SqlParameter VersionQFEParam = new SqlParameter("@VersionQFE", SqlDbType.Int);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter AutoResponseParam = new SqlParameter("@AutoResponse", SqlDbType.Xml);
                    SqlParameter IsPublicParam = new SqlParameter("@IsPublic", SqlDbType.Bit);
                    SqlParameter IsActiveParam = new SqlParameter("@IsActive", SqlDbType.Bit);
                    SqlParameter IsTestableParam = new SqlParameter("@IsTestable", SqlDbType.Bit);
                    SqlParameter RequestTransformParam = new SqlParameter("@RequestTransform", SqlDbType.Xml);
                    SqlParameter ResponseTransformParam = new SqlParameter("@ResponseTransform", SqlDbType.Xml);
                    SqlParameter ResourceIDParam = new SqlParameter("@ResourceID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = operationVersion.ID;
                    VersionMajorParam.Value = int.Parse(operationVersion.Version.Major);
                    VersionMinorParam.Value = int.Parse(operationVersion.Version.Minor);
                    VersionBuildParam.Value = int.Parse(operationVersion.Version.Build);
                    VersionQFEParam.Value = int.Parse(operationVersion.Version.Qfe);
                    DescriptionParam.Value = operationVersion.Description;
                    if (operationVersion.AutoResponse != null)
                    {
                        AutoResponseParam.Value = operationVersion.AutoResponse.OuterXml;
                    }
                    else
                    {
                        AutoResponseParam.Value = DBNull.Value;
                    }
                    IsPublicParam.Value = operationVersion.IsPublic;
                    IsActiveParam.Value = operationVersion.IsActive;
                    IsTestableParam.Value = operationVersion.IsTestable;
                    if (operationVersion.RequestTransformXSLT != null)
                    {
                        RequestTransformParam.Value = operationVersion.RequestTransformXSLT.OuterXml;
                    }
                    else
                    {
                        RequestTransformParam.Value = DBNull.Value;
                    }
                    if (operationVersion.ResponseTransformXSLT != null)
                    {
                        ResponseTransformParam.Value = operationVersion.ResponseTransformXSLT.OuterXml;
                    }
                    else
                    {
                        ResponseTransformParam.Value = DBNull.Value;
                    }
                    if (operationVersion.Resource != null)
                    {
                        if (operationVersion.Resource.ID.Equals(Guid.Empty))
                        {
                            ResourceIDParam.Value = CreateResource(operationVersion.Resource, txn, conn);
                        }
                        else
                        {
                            ResourceIDParam.Value = operationVersion.Resource.ID;
                        }
                    }
                    else
                    {
                        ResourceIDParam.Value = null;
                        //throw new ApplicationException("CreateOperationVersion requires ChannelType, but no ChannelType was supplied");
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(VersionMajorParam);
                    cmd.Parameters.Add(VersionMinorParam);
                    cmd.Parameters.Add(VersionBuildParam);
                    cmd.Parameters.Add(VersionQFEParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(AutoResponseParam);
                    cmd.Parameters.Add(IsPublicParam);
                    cmd.Parameters.Add(IsActiveParam);
                    cmd.Parameters.Add(IsTestableParam);
                    cmd.Parameters.Add(RequestTransformParam);
                    cmd.Parameters.Add(ResponseTransformParam);
                    cmd.Parameters.Add(ResourceIDParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;

                    int partNo = 0;

                    DeleteMessagesFromOperationVersion(ID, txn, conn);

                    if (operationVersion.RequestMsg != null)
                    {
                        foreach (MessagePart part in operationVersion.RequestMsg)
                        {
                            CreateMessagePart(part, ID, partNo++, SC.IsRequestMsg, txn, conn);
                        }
                    }

                    if (operationVersion.ResponseMsg != null)
                    {
                        partNo = 0;
                        foreach (MessagePart part in operationVersion.ResponseMsg)
                        {
                            CreateMessagePart(part, ID, partNo++, SC.IsResponseMsg, txn, conn);
                        }
                    }

                }

                //send notification to affected runtimes
                if (trackChanges)
                {
                    RepositoryChangeManager.RecordChange(DBEvents.OperationsUpdated, DBChangeType.Update, eventData, txn, conn);
                }

                if ((autoclose) && (txn != null)) txn.Commit();
                
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return operationVersion;
        }

        private static void DeleteVersionsFromOperation(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteVersionsFromOperation]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                try
                {
                    eventData = DAL.ListRuntimeServersForOperationID(ID, txn, conn);
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in DeleteVersionsFromOperation.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                //send notification to affected runtimes
                RepositoryChangeManager.RecordChange(DBEvents.OperationsUpdated, DBChangeType.Delete, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        private static void DeleteMessagesFromOperationVersion(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteMessagesFromOperationVersion]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        private static void DeleteSoapFaults(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteSoapFaultsForOperationVersion]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        private static void DeleteSoapFault(Guid ID, Guid soapFaultID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteSoapFaultForOperationVersion]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter FaultIDParam = new SqlParameter("@SoapFaultID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    FaultIDParam.Value = soapFaultID;
                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(FaultIDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void AssignBindingElementsToBinding(Guid bindingID, Guid bindingElementID, int elementOrder, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[AssignBindingElementsToBinding]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                //Note: No change tracking needed for newly activated operations at an endpoint
                //brokers will query for the operation to resolve since it won't be in the broker cache

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter BindingElementIDParam = new SqlParameter("@BindingElementID", SqlDbType.UniqueIdentifier);
                    SqlParameter ElementOrderParam = new SqlParameter("@ElementOrder", SqlDbType.TinyInt);


                    cmd.CommandType = CommandType.StoredProcedure;
                    BindingIDParam.Value = bindingID;
                    BindingElementIDParam.Value = bindingElementID;
                    ElementOrderParam.Value = elementOrder;

                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(BindingElementIDParam);
                    cmd.Parameters.Add(ElementOrderParam);


                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void RemoveBindingElementsFromBinding(Guid bindingID, Guid bindingElementID, int elementOrder, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[RemoveBindingElementsFromBinding]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                MSEBindingElement bindingElement = null;
                try
                {
                    eventData = DAL.ListRuntimeServersForBindingID(bindingID, txn, conn);
                    bindingElement = DAL.GetMSEBindingElement(bindingElementID, txn, conn);
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in RemoveAssociatedOperationVersionFromEndpoint.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter BindingElementIDParam = new SqlParameter("@BindingElementID", SqlDbType.UniqueIdentifier);
                    SqlParameter ElementOrderParam = new SqlParameter("@ElementOrder", SqlDbType.TinyInt);


                    cmd.CommandType = CommandType.StoredProcedure;
                    BindingIDParam.Value = bindingID;
                    BindingElementIDParam.Value = bindingElementID;
                    ElementOrderParam.Value = elementOrder;

                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(BindingElementIDParam);
                    cmd.Parameters.Add(ElementOrderParam);

                    cmd.ExecuteNonQuery();
                }

                //TODO send notification to affected runtimes
                //eventData.ForEach(item => { item.OperationId = bindingElement == null ? Guid.Empty : opver.OperationID; });
                //RepositoryChangeManager.RecordChange(DBEvents.RuntimeServersBindingUpdated, DBChangeType.Delete, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void AssignAssociatedOperationVersionToEndpoint(Guid operationVersionID, Guid endpointID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[AssignAssociatedOperationVersionToEndpoint]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                //Note: No change tracking needed for newly activated operations at an endpoint
                //brokers will query for the operation to resolve since it won't be in the broker cache

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter OperationVersionIDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    OperationVersionIDParam.Value = operationVersionID;
                    cmd.Parameters.Add(OperationVersionIDParam);
                    EndpointIDParam.Value = endpointID;
                    cmd.Parameters.Add(EndpointIDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        private static List<DBEventDataItem> ListRuntimeServersForEndpointID(Guid endpointID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<DBEventDataItem> list = new List<DBEventDataItem>();
            const string sprocname = "[ServiceEngine].[ListRuntimeServersForEndpointID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    EndpointIDParam.Value = endpointID;
                    cmd.Parameters.Add(EndpointIDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                DBEventDataItem element = new DBEventDataItem();
                                element.RuntimeServerId = reader.GetGuid(0);
                                element.EndpointId = reader.GetGuid(1);
                                list.Add(element);
                            }
                        }
                    }
                }

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return list;

        }

        private static List<DBEventDataItem> ListRuntimeServersForChannelID(Guid channelID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<DBEventDataItem> list = new List<DBEventDataItem>();
            const string sprocname = "[ServiceEngine].[ListRuntimeServersForChannelID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter ChannelIDParam = new SqlParameter("@ChannelID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    ChannelIDParam.Value = channelID;
                    cmd.Parameters.Add(ChannelIDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                DBEventDataItem element = new DBEventDataItem();
                                element.RuntimeServerId = reader.GetGuid(0);
                                element.EndpointId = reader.GetGuid(1);
                                element.OperationId = reader.GetGuid(2);
                                list.Add(element);
                            }
                        }
                    }
                }

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return list;

        }
        
        private static List<DBEventDataItem> ListRuntimeServersForOperationID(Guid operationID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<DBEventDataItem> list = new List<DBEventDataItem>();
            const string sprocname = "[ServiceEngine].[ListRuntimeServersForOperationID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter OperationIDParam = new SqlParameter("@OperationID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    OperationIDParam.Value = operationID;
                    cmd.Parameters.Add(OperationIDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                DBEventDataItem element = new DBEventDataItem();
                                element.RuntimeServerId = reader.GetGuid(0);
                                element.EndpointId = reader.GetGuid(1);
                                element.OperationId = reader.GetGuid(2);
                                list.Add(element);
                            }
                        }
                    }
                }

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return list;

        }
        
        private static List<DBEventDataItem> ListRuntimeServersForOperationVersionID(Guid operationVersionID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<DBEventDataItem> list = new List<DBEventDataItem>();
            const string sprocname = "[ServiceEngine].[ListRuntimeServersForOperationVersionID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter opVersionIDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    opVersionIDParam.Value = operationVersionID;
                    cmd.Parameters.Add(opVersionIDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                DBEventDataItem element = new DBEventDataItem();
                                element.RuntimeServerId = reader.GetGuid(0);
                                element.EndpointId = reader.GetGuid(1);
                                element.OperationId = reader.GetGuid(2);
                                list.Add(element);
                            }
                        }
                    }
                }

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return list;

        }
        
        private static List<DBEventDataItem> ListRuntimeServersForBindingID(Guid bindingID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<DBEventDataItem> list = new List<DBEventDataItem>();
            const string sprocname = "[ServiceEngine].[ListRuntimeServersForBindingID]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter OperationIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    OperationIDParam.Value = bindingID;
                    cmd.Parameters.Add(OperationIDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                DBEventDataItem element = new DBEventDataItem();
                                element.RuntimeServerId = reader.GetGuid(0);
                                list.Add(element);
                            }
                        }
                    }
                }

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return list;

        }

        public static RuntimeServerNotificationList ListRuntimeServerNotificationAddresses(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            RuntimeServerNotificationList list = new RuntimeServerNotificationList();
            const string sprocname = "[ServiceEngine].[ListRuntimeServerNotificationAddresses]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.RuntimeServers = new List<RuntimeServerNotificationListElement>();
                            while (reader.Read())
                            {
                                RuntimeServerNotificationListElement element = new RuntimeServerNotificationListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                element.NotificationUrl = reader.GetString(2);
                                element.BindingID = reader.GetGuid(3);
                                XmlDocument xdoc = new XmlDocument();
                                SqlXml sqlxml = reader.GetSqlXml(4);
                                if (sqlxml != null && !sqlxml.IsNull)
                                {
                                    xdoc.Load(sqlxml.CreateReader());
                                    element.Binding = xdoc.DocumentElement;
                                }
                                list.RuntimeServers.Add(element);
                            }
                        }
                    }
                }

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return list;
        }
        
        public static void RemoveAssociatedOperationVersionFromEndpoint(Guid operationVersionID, Guid endpointID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[RemoveAssociatedOperationFromEndpoint]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                OperationVersion opver = null;
                try
                {
                    eventData = DAL.ListRuntimeServersForEndpointID(endpointID, txn, conn);
                    opver = DAL.GetOperationVersion(operationVersionID, txn, conn);
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in RemoveAssociatedOperationVersionFromEndpoint.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter OperationVersionIDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    OperationVersionIDParam.Value = operationVersionID;
                    cmd.Parameters.Add(OperationVersionIDParam);
                    EndpointIDParam.Value = endpointID;
                    cmd.Parameters.Add(EndpointIDParam);

                    cmd.ExecuteNonQuery();
                }

                //send notification to affected runtimes
                eventData.ForEach(item => { item.OperationId = opver == null ? Guid.Empty : opver.OperationID; });
                RepositoryChangeManager.RecordChange(DBEvents.EndpointOpAssociationUpdated, DBChangeType.Delete, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void AssignPublishedOperationVersionToEndpoint(Guid operationVersionID, Guid endpointID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[AssignPublishedOperationVersionToEndpoint]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                OperationVersion opver = null;
                try
                {
                    eventData = DAL.ListRuntimeServersForEndpointID(endpointID, txn, conn);
                    opver = DAL.GetOperationVersion(operationVersionID, txn, conn);
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in AssignPublishedOperationVersionToEndpoint.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter OperationVersionIDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    OperationVersionIDParam.Value = operationVersionID;
                    cmd.Parameters.Add(OperationVersionIDParam);
                    EndpointIDParam.Value = endpointID;
                    cmd.Parameters.Add(EndpointIDParam);

                    cmd.ExecuteNonQuery();
                }

                // Update any UDDI associations 
                eventData.ForEach(item => { PublishEndPointToUddi(endpointID, item.RuntimeServerId, false, txn, conn); });

                //send notification to affected runtimes
                eventData.ForEach(item => {item.OperationId = opver == null ? Guid.Empty : opver.OperationID;});
                RepositoryChangeManager.RecordChange(DBEvents.EndpointOpPublicationUpdated, DBChangeType.Create, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static void RemovePublishedOperationVersionFromEndpoint(Guid operationVersionID, Guid endpointID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[RemovePublishedOperationFromEndpoint]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking

                //get list of runtimes affected
                List<DBEventDataItem> eventData = null;
                OperationVersion opver = null;
                try
                {
                    eventData = DAL.ListRuntimeServersForEndpointID(endpointID, txn, conn);
                    opver = DAL.GetOperationVersion(operationVersionID, txn, conn);
                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in RemovePublishedOperationVersionFromEndpoint.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }

                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter OperationVersionIDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    OperationVersionIDParam.Value = operationVersionID;
                    cmd.Parameters.Add(OperationVersionIDParam);
                    EndpointIDParam.Value = endpointID;
                    cmd.Parameters.Add(EndpointIDParam);

                    cmd.ExecuteNonQuery();
                }

                OperationVersionList pubOpVersionsList = ListPublishedOperationsForEndpoint(endpointID, txn, conn);
                if (pubOpVersionsList == null ||
                    pubOpVersionsList.OperationVersions == null ||
                    pubOpVersionsList.OperationVersions.Count == 0)
                {
                    // Remove any UDDI associations 
                    eventData.ForEach(item => { RemoveEndPointFromUddi(endpointID, item.RuntimeServerId, txn, conn); });
                }

                //send notification to affected runtimes
                eventData.ForEach(item => { item.OperationId = opver == null ? Guid.Empty : opver.OperationID; });
                RepositoryChangeManager.RecordChange(DBEvents.EndpointOpPublicationUpdated, DBChangeType.Delete, eventData, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }
        
        public static PolicyList ListPolicies(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            PolicyList list = new PolicyList();
            const string sprocname = "[ServiceEngine].[ListPolicies]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Policies = new List<PolicyListElement>();
                            while (reader.Read())
                            {
                                PolicyListElement element = new PolicyListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Policies.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static Guid CreatePolicy(Policy policy, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreatePolicy]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter PolicyParam = new SqlParameter("@Policy", SqlDbType.Xml);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = policy.Name;
                    if (policy.WSPolicy != null)
                    {
                        PolicyParam.Value = policy.WSPolicy.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreatePolicy failed: WSPolicy is a required element but was not sent");
                    }
                    DescriptionParam.Value = policy.Description;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(PolicyParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static void DeletePolicy(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeletePolicy]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static Policy UpdatePolicy(Policy policy, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdatePolicy]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                List<DBEventDataItem> eventDataEP = new List<DBEventDataItem>();
                List<DBEventDataItem> eventDataOP = new List<DBEventDataItem>();
                try
                {
                    //identify where policy is used
                    EndpointList epList = DAL.ListEndpointsForPolicyID(policy.ID, txn, conn);
                    ChannelList chList = DAL.ListChannelsForPolicyID(policy.ID, txn, conn);
                    //get affected runtimes
                    if (epList != null && epList.Endpoints != null)
                    {
                        foreach (EndpointListElement element in epList.Endpoints)
                        {
                            List<DBEventDataItem> temp = DAL.ListRuntimeServersForEndpointID(element.ID, txn, conn);
                            temp.ForEach(item => { if (!eventDataEP.Contains(item)) eventDataEP.Add(item); });
                        }
                    }
                    if (chList != null && chList.Channels != null)
                    {
                        foreach (ChannelListElement element in chList.Channels)
                        {
                            List<DBEventDataItem> temp = DAL.ListRuntimeServersForChannelID(element.ID, txn, conn);
                            temp.ForEach(item => { if (!eventDataOP.Contains(item)) eventDataOP.Add(item); });
                        }
                    }

                    //consolidate eventdata
                    //if EndpointsUpdated event is going to be thrown for an Endpoint, there is no need to throw OperationsUpdated events for the same endpoint
                    //broker will flush cache based on an endpoint being updated
                    if (eventDataEP != null && eventDataEP.Count > 0 && eventDataOP != null && eventDataOP.Count > 0)
                    {
                        foreach (DBEventDataItem epItem in eventDataEP)
                        {
                            for (int i = eventDataOP.Count - 1; i >= 0; i--)
                            {
                                if (epItem.RuntimeServerId == eventDataOP[i].RuntimeServerId && epItem.EndpointId == eventDataOP[i].EndpointId)
                                    eventDataOP.RemoveAt(i);
                            }
                        }
                    }

                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in UpdatePolicy.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }
                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter PolicyParam = new SqlParameter("@Policy", SqlDbType.Xml);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = policy.ID;
                    NameParam.Value = policy.Name;
                    if (policy.WSPolicy != null)
                    {
                        PolicyParam.Value = policy.WSPolicy.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("UpdatePolicy failed: WSPolicy is a required element but was not sent");
                    }
                    DescriptionParam.Value = policy.Description;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(PolicyParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();
                }

                //send notification to affected runtimes
                RepositoryChangeManager.RecordChange(DBEvents.EndpointsUpdated, DBChangeType.Update, eventDataEP, txn, conn);
                RepositoryChangeManager.RecordChange(DBEvents.OperationsUpdated, DBChangeType.Update, eventDataOP, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return policy;
        }

        //SystemInstances
        public static SystemInstanceList ListSystemInstances(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SystemInstanceList list = new SystemInstanceList();
            const string sprocname = "[ServiceEngine].[ListSystemInstances]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.SystemInstances = new List<SystemInstanceListElement>();
                            while (reader.Read())
                            {
                                SystemInstanceListElement element = new SystemInstanceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.SystemInstances.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static SystemInstanceList ListSystemInstancesForSystem(Guid systemID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SystemInstanceList list = new SystemInstanceList();
            const string sprocname = "[ServiceEngine].[ListSystemInstancesForSystem]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@SystemID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = systemID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.SystemInstances = new List<SystemInstanceListElement>();
                            while (reader.Read())
                            {
                                SystemInstanceListElement element = new SystemInstanceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.SystemInstances.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }
        //system

        public static SystemList ListSystems(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SystemList list = new SystemList();
            const string sprocname = "[ServiceEngine].[ListSystems]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Systems = new List<SystemListElement>();
                            while (reader.Read())
                            {
                                SystemListElement element = new SystemListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Systems.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<SystemListElement> ListSystemsByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<SystemListElement> list = new List<SystemListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<SystemListElement>();
                            while (reader.Read())
                            {
                                SystemListElement element = new SystemListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static Guid CreateSystem(MSEContracts.System system, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateSystem]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter OwnerNameParam = new SqlParameter("@OwnerName", SqlDbType.NText);
                    SqlParameter OwnerContactParam = new SqlParameter("@OwnerContact", SqlDbType.NChar,10);
                    SqlParameter LocationParam = new SqlParameter("@Location", SqlDbType.NText);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = system.Name;
                    OwnerNameParam.Value = system.OwnerName;
                    OwnerContactParam.Value = system.OwnerContact;
                    LocationParam.Value = system.Location;
                    DescriptionParam.Value = system.Description;
                    if (system.Policy != null)
                    {
                        PolicyIDParam.Value = system.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(OwnerNameParam);
                    cmd.Parameters.Add(OwnerContactParam);
                    cmd.Parameters.Add(LocationParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(PolicyIDParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static MSEContracts.System GetSystem(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            MSEContracts.System system = new MSEContracts.System();
            const string sprocname = "[ServiceEngine].[GetSystem]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            system.ID = reader.GetGuid(0);
                            system.Name = reader.GetString(1);
                            if (reader.IsDBNull(2))
                            {
                               system.OwnerName = null;
                            }
                            else
                            {
                                system.OwnerName = reader.GetString(2);
                            }
                            if (reader.IsDBNull(3))
                            {
                                system.Location = null;
                            }
                            else
                            {
                                system.Location = reader.GetString(3);
                            }

                            if (reader.IsDBNull(4))
                            {
                                system.Description = null;
                            }
                            else
                            {
                                system.Description = reader.GetString(4);
                            }
                            if (reader.IsDBNull(5))
                            {
                                system.OwnerContact = null;
                            }
                            else
                            {
                                system.OwnerContact = reader.GetString(5);
                            }
                            system.Policy = reader.IsDBNull(6) ? null : GetPolicy(reader.GetGuid(6), txn, conn);

                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return system;

        }

        public static void DeleteSystem(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteSystem]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static MSEContracts.System UpdateSystem(MSEContracts.System system, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateSystem]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter OwnerNameParam = new SqlParameter("@OwnerName", SqlDbType.NText);
                    SqlParameter OwnerContactParam = new SqlParameter("@OwnerContact", SqlDbType.NChar,10);
                    SqlParameter LocationParam = new SqlParameter("@Location", SqlDbType.NText);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = system.ID;
                    NameParam.Value = system.Name;
                    OwnerNameParam.Value = system.OwnerName;
                    OwnerContactParam.Value = system.OwnerContact;
                    LocationParam.Value = system.Location;
                    DescriptionParam.Value = system.Description;
                    if (system.Policy != null)
                    {
                        PolicyIDParam.Value = system.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(OwnerNameParam);
                    cmd.Parameters.Add(OwnerContactParam);
                    cmd.Parameters.Add(LocationParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(PolicyIDParam);

                    cmd.ExecuteNonQuery();
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return system;
        }

        public static Guid CreateSystemInstance(MSEContracts.SystemInstance systemInstance, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateSystemInstance]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter SystemIDParam = new SqlParameter("@SystemID", SqlDbType.UniqueIdentifier);
                    SqlParameter OwnerNameParam = new SqlParameter("@OwnerName", SqlDbType.NVarChar, 200);
                    SqlParameter OwnerContactParam = new SqlParameter("@OwnerContact", SqlDbType.NVarChar, 200);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar,500);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    SystemIDParam.Value = systemInstance.SystemID;
                    NameParam.Value = systemInstance.Name;
                    OwnerNameParam.Value = systemInstance.OwnerName;
                    OwnerContactParam.Value = systemInstance.OwnerContact;
                    URIParam.Value = systemInstance.URI;
                    DescriptionParam.Value = systemInstance.Description;
                    if (systemInstance.Policy != null)
                    {
                        PolicyIDParam.Value = systemInstance.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(SystemIDParam);
                    cmd.Parameters.Add(OwnerNameParam);
                    cmd.Parameters.Add(OwnerContactParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(PolicyIDParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static MSEContracts.SystemInstance UpdateSystemInstance(MSEContracts.SystemInstance systemInstance, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateSystemInstance]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter SystemIDParam = new SqlParameter("@SystemID", SqlDbType.UniqueIdentifier);
                    SqlParameter OwnerNameParam = new SqlParameter("@OwnerName", SqlDbType.NVarChar, 200);
                    SqlParameter OwnerContactParam = new SqlParameter("@OwnerContact", SqlDbType.NChar, 200);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar, 500);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = systemInstance.ID;
                    SystemIDParam.Value = systemInstance.SystemID;
                    NameParam.Value = systemInstance.Name;
                    OwnerNameParam.Value = systemInstance.OwnerName;
                    OwnerContactParam.Value = systemInstance.OwnerContact;
                    URIParam.Value = systemInstance.URI;
                    DescriptionParam.Value = systemInstance.Description;
                    if (systemInstance.Policy != null)
                    {
                        PolicyIDParam.Value = systemInstance.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }


                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(SystemIDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(OwnerNameParam);
                    cmd.Parameters.Add(OwnerContactParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(PolicyIDParam);

                    cmd.ExecuteNonQuery();
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return systemInstance;
        }

        public static void DeleteSystemInstance(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteSystemInstance]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static MSEContracts.SystemInstance GetSystemInstance(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            MSEContracts.SystemInstance systemInstance = new MSEContracts.SystemInstance();
            const string sprocname = "[ServiceEngine].[GetSystemInstance]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    //SELECT	N.[EntityID] as SystemInstanceID, N.[EntityName] as [Name], 
                    //SI.SystemID, SI.OwnerName, SI.URI, N.EntityDescription as Description, S.OwnerContact, S.PolicyID

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            systemInstance.ID = reader.GetGuid(0);
                            systemInstance.Name = reader.GetString(1);
                            systemInstance.SystemID = reader.GetGuid(2);

                            if (reader.IsDBNull(3))
                            {
                                systemInstance.OwnerName = null;
                            }
                            else
                            {
                                systemInstance.OwnerName = reader.GetString(3);
                            }
                            if (reader.IsDBNull(4))
                            {
                                systemInstance.URI = null;
                            }
                            else
                            {
                                systemInstance.URI = reader.GetString(4);
                            }
                            if (reader.IsDBNull(5))
                            {
                                systemInstance.Description = null;
                            }
                            else
                            {
                                systemInstance.Description = reader.GetString(5);
                            }
                            if (reader.IsDBNull(6))
                            {
                                systemInstance.OwnerContact = null;
                            }
                            else
                            {
                                systemInstance.OwnerContact = reader.GetString(6);
                            }

                            systemInstance.Policy = reader.IsDBNull(7) ? null : GetPolicy(reader.GetGuid(7), txn, conn);

                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return systemInstance;

        }

        public static SystemGroup CreateSystemGroup(SystemGroup systemGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            systemGroup.ID = CreateEntityGroup(systemGroup.Name, systemGroup.Description, 12, txn, conn);

            if ((autoclose) && (txn != null)) txn.Commit();

            return systemGroup;
        }

        public static SystemGroup GetSystemGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SystemGroup systemGroup = new SystemGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                systemGroup.ID = entityGroup.ID;
                systemGroup.Name = entityGroup.Name;
                systemGroup.Description = entityGroup.Description;

                systemGroup.Systems = ListSystemsByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return systemGroup;
        }

        public static SystemGroup UpdateSystemGroup(SystemGroup systemGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(systemGroup.ID, systemGroup.Name, systemGroup.Description, txn, conn);

                List<SystemListElement> oldList = ListSystemsByGroup(systemGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (SystemListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(systemGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (systemGroup.Systems != null)
                {
                    foreach (SystemListElement newListElement in systemGroup.Systems)
                    {
                        AssignEntityToEntityGroup(systemGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return systemGroup;
        }
    

        //resource

        public static ResourceList ListResources(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceList list = new ResourceList();
            const string sprocname = "[ServiceEngine].[ListResources]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Resources = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Resources.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static ResourceList ListResourcesForSystemInstance(Guid InstanceID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceList list = new ResourceList();
            const string sprocname = "[ServiceEngine].[ListResourcesForSystemInstance]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = InstanceID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Resources = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Resources.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<ResourceListElement> ListResourcesByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<ResourceListElement> list = new List<ResourceListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static Guid CreateResource(Resource resource, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter InstanceIDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDLParam = new SqlParameter("@IDL", SqlDbType.NVarChar);
                    SqlParameter IDLTypeParam = new SqlParameter("@IDLType", SqlDbType.NChar,100);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter MonikerParam = new SqlParameter("@Moniker", SqlDbType.Xml);
                    SqlParameter RequestEntityParam = new SqlParameter("@RequestEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter ResponseEntityParam = new SqlParameter("@ResponseEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter ShareableProxyParam = new SqlParameter("@ShareableProxy", SqlDbType.Bit);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = resource.Name;
                    DescriptionParam.Value = resource.Description;
                    InstanceIDParam.Value = resource.InstanceID;
                    IDLParam.Value = resource.IDL;
                    IDLTypeParam.Value = resource.IDLType;
                    BindingIDParam.Value = resource.Binding.ID;
                    if (resource.Moniker != null)
                    {
                        MonikerParam.Value = resource.Moniker.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateResource failed: Moniker is a required element but was not sent");
                    }                    
                    RequestEntityParam.Value = resource.RequestEntityID;
                    ResponseEntityParam.Value = resource.ResponseEntityID;
                    URIParam.Value = resource.URI;
                    ShareableProxyParam.Value = resource.ShareableProxy;
                    if (resource.Policy != null)
                    {
                        PolicyIDParam.Value = resource.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    } 


                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(InstanceIDParam);
                    cmd.Parameters.Add(IDLParam);
                    cmd.Parameters.Add(IDLTypeParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(MonikerParam);
                    cmd.Parameters.Add(RequestEntityParam);
                    cmd.Parameters.Add(ResponseEntityParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(ShareableProxyParam);


                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static Resource GetResource(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Resource resource = new Resource();
            const string sprocname = "[ServiceEngine].[GetResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            resource.ID = reader.GetGuid(0);
                            resource.Name = reader.GetString(1);
                            resource.InstanceID = reader.GetGuid(2);
                            if (reader.IsDBNull(3))
                            {
                                resource.IDL = null;
                            }
                            else
                            {
                                resource.IDL = reader.GetString(3);
                            }
                            if (reader.IsDBNull(4))
                            {
                                resource.IDLType = null;
                            }
                            else
                            {
                                resource.IDLType = reader.GetString(4);
                            }

                            resource.Binding = reader.IsDBNull(5) ? null : GetMSEBinding(reader.GetGuid(5), txn, conn);

                            if (reader.IsDBNull(6))
                            {
                                resource.Moniker = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(6).CreateReader());
                                resource.Moniker = xdoc.DocumentElement;
                            }
                            if (reader.IsDBNull(7))
                            {
                                resource.Description = null;
                            }
                            else
                            {
                                resource.Description = reader.GetString(7);
                            }

                            if (!reader.IsDBNull(8))
                            {
                                resource.RequestEntityID = reader.GetGuid(8);
                            }

                            if (!reader.IsDBNull(9))
                            {
                                resource.ResponseEntityID = reader.GetGuid(9);
                            }

                            if (reader.IsDBNull(10))
                            {
                                resource.URI = null;
                            }
                            else
                            {
                                resource.URI = reader.GetString(10);
                            }

                            //TODO may need to get policies from systemInstance and system and create a composite policy
                            resource.Policy = reader.IsDBNull(11) ? null : GetPolicy(reader.GetGuid(11), txn, conn);

                            resource.ShareableProxy = reader.GetBoolean(12);

                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return resource;

        }

        public static void DeleteResource(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static Resource UpdateResource(Resource resource, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter InstanceIDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDLParam = new SqlParameter("@IDL", SqlDbType.NVarChar);
                    SqlParameter IDLTypeParam = new SqlParameter("@IDLType", SqlDbType.NChar, 100);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter MonikerParam = new SqlParameter("@Moniker", SqlDbType.Xml);
                    SqlParameter RequestEntityParam = new SqlParameter("@RequestEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter ResponseEntityParam = new SqlParameter("@ResponseEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter ShareableProxyParam = new SqlParameter("@ShareableProxy", SqlDbType.Bit);


                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = resource.ID;
                    NameParam.Value = resource.Name;
                    InstanceIDParam.Value = resource.InstanceID;
                    IDLParam.Value = resource.IDL;
                    IDLTypeParam.Value = resource.IDLType;
                    DescriptionParam.Value = resource.Description;
                    BindingIDParam.Value = resource.Binding.ID;
                    if (resource.Moniker != null)
                    {
                        MonikerParam.Value = resource.Moniker.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateResource failed: Moniker is a required element but was not sent");
                    } 
                    RequestEntityParam.Value = resource.RequestEntityID;
                    ResponseEntityParam.Value = resource.ResponseEntityID;
                    URIParam.Value = resource.URI;
                    ShareableProxyParam.Value = resource.ShareableProxy;
                    if (resource.Policy != null)
                    {
                        PolicyIDParam.Value = resource.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    } 

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(InstanceIDParam);
                    cmd.Parameters.Add(IDLParam);
                    cmd.Parameters.Add(IDLTypeParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(MonikerParam);
                    cmd.Parameters.Add(RequestEntityParam);
                    cmd.Parameters.Add(ResponseEntityParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(ShareableProxyParam);

                    cmd.ExecuteNonQuery();
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return resource;
        }

        public static ResourceGroup CreateResourceGroup(ResourceGroup resourceGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            resourceGroup.ID = CreateEntityGroup(resourceGroup.Name, resourceGroup.Description, 14, txn, conn);

            if ((autoclose) && (txn != null)) txn.Commit();

            return resourceGroup;
        }

        public static ResourceGroup GetResourceGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceGroup resourceGroup = new ResourceGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                resourceGroup.ID = entityGroup.ID;
                resourceGroup.Name = entityGroup.Name;
                resourceGroup.Description = entityGroup.Description;

                resourceGroup.Resources = ListResourcesByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return resourceGroup;
        }

        public static ResourceGroup UpdateResourceGroup(ResourceGroup resourceGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(resourceGroup.ID, resourceGroup.Name, resourceGroup.Description, txn, conn);

                List<ResourceListElement> oldList = ListResourcesByGroup(resourceGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (ResourceListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(resourceGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (resourceGroup.Resources != null)
                {
                    foreach (ResourceListElement newListElement in resourceGroup.Resources)
                    {
                        AssignEntityToEntityGroup(resourceGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return resourceGroup;
        }

        #region capability

        public static CapabilityList ListCapabilities(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            CapabilityList list = new CapabilityList();
            const string sprocname = "[ServiceEngine].[ListCapabilities]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.CapabilityList = new List<CapabilityListElement>();
                            while (reader.Read())
                            {
                                CapabilityListElement element = new CapabilityListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Capabilities.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static CapabilityList ListCapabilitiesForActor(Guid ProcessID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceList list = new ResourceList();
            const string sprocname = "[ServiceEngine].[ListResourcesForSystemInstance]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = InstanceID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Resources = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Resources.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<CapabilityListElement> ListCapabilitiesByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<ResourceListElement> list = new List<ResourceListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static Guid CreateCapability(Capability capability, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter InstanceIDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDLParam = new SqlParameter("@IDL", SqlDbType.NVarChar);
                    SqlParameter IDLTypeParam = new SqlParameter("@IDLType", SqlDbType.NChar, 100);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter MonikerParam = new SqlParameter("@Moniker", SqlDbType.Xml);
                    SqlParameter RequestEntityParam = new SqlParameter("@RequestEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter ResponseEntityParam = new SqlParameter("@ResponseEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter ShareableProxyParam = new SqlParameter("@ShareableProxy", SqlDbType.Bit);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = resource.Name;
                    DescriptionParam.Value = resource.Description;
                    InstanceIDParam.Value = resource.InstanceID;
                    IDLParam.Value = resource.IDL;
                    IDLTypeParam.Value = resource.IDLType;
                    BindingIDParam.Value = resource.Binding.ID;
                    if (resource.Moniker != null)
                    {
                        MonikerParam.Value = resource.Moniker.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateResource failed: Moniker is a required element but was not sent");
                    }
                    RequestEntityParam.Value = resource.RequestEntityID;
                    ResponseEntityParam.Value = resource.ResponseEntityID;
                    URIParam.Value = resource.URI;
                    ShareableProxyParam.Value = resource.ShareableProxy;
                    if (resource.Policy != null)
                    {
                        PolicyIDParam.Value = resource.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }


                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(InstanceIDParam);
                    cmd.Parameters.Add(IDLParam);
                    cmd.Parameters.Add(IDLTypeParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(MonikerParam);
                    cmd.Parameters.Add(RequestEntityParam);
                    cmd.Parameters.Add(ResponseEntityParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(ShareableProxyParam);


                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static Capability GetCapability(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Resource resource = new Resource();
            const string sprocname = "[ServiceEngine].[GetResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            resource.ID = reader.GetGuid(0);
                            resource.Name = reader.GetString(1);
                            resource.InstanceID = reader.GetGuid(2);
                            if (reader.IsDBNull(3))
                            {
                                resource.IDL = null;
                            }
                            else
                            {
                                resource.IDL = reader.GetString(3);
                            }
                            if (reader.IsDBNull(4))
                            {
                                resource.IDLType = null;
                            }
                            else
                            {
                                resource.IDLType = reader.GetString(4);
                            }

                            resource.Binding = reader.IsDBNull(5) ? null : GetMSEBinding(reader.GetGuid(5), txn, conn);

                            if (reader.IsDBNull(6))
                            {
                                resource.Moniker = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(6).CreateReader());
                                resource.Moniker = xdoc.DocumentElement;
                            }
                            if (reader.IsDBNull(7))
                            {
                                resource.Description = null;
                            }
                            else
                            {
                                resource.Description = reader.GetString(7);
                            }

                            if (!reader.IsDBNull(8))
                            {
                                resource.RequestEntityID = reader.GetGuid(8);
                            }

                            if (!reader.IsDBNull(9))
                            {
                                resource.ResponseEntityID = reader.GetGuid(9);
                            }

                            if (reader.IsDBNull(10))
                            {
                                resource.URI = null;
                            }
                            else
                            {
                                resource.URI = reader.GetString(10);
                            }

                            //TODO may need to get policies from systemInstance and system and create a composite policy
                            resource.Policy = reader.IsDBNull(11) ? null : GetPolicy(reader.GetGuid(11), txn, conn);

                            resource.ShareableProxy = reader.GetBoolean(12);

                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return resource;

        }

        public static void DeleteCapability(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static Capability UpdateCapability(Capability capability, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter InstanceIDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDLParam = new SqlParameter("@IDL", SqlDbType.NVarChar);
                    SqlParameter IDLTypeParam = new SqlParameter("@IDLType", SqlDbType.NChar, 100);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter MonikerParam = new SqlParameter("@Moniker", SqlDbType.Xml);
                    SqlParameter RequestEntityParam = new SqlParameter("@RequestEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter ResponseEntityParam = new SqlParameter("@ResponseEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter ShareableProxyParam = new SqlParameter("@ShareableProxy", SqlDbType.Bit);


                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = resource.ID;
                    NameParam.Value = resource.Name;
                    InstanceIDParam.Value = resource.InstanceID;
                    IDLParam.Value = resource.IDL;
                    IDLTypeParam.Value = resource.IDLType;
                    DescriptionParam.Value = resource.Description;
                    BindingIDParam.Value = resource.Binding.ID;
                    if (resource.Moniker != null)
                    {
                        MonikerParam.Value = resource.Moniker.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateResource failed: Moniker is a required element but was not sent");
                    }
                    RequestEntityParam.Value = resource.RequestEntityID;
                    ResponseEntityParam.Value = resource.ResponseEntityID;
                    URIParam.Value = resource.URI;
                    ShareableProxyParam.Value = resource.ShareableProxy;
                    if (resource.Policy != null)
                    {
                        PolicyIDParam.Value = resource.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(InstanceIDParam);
                    cmd.Parameters.Add(IDLParam);
                    cmd.Parameters.Add(IDLTypeParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(MonikerParam);
                    cmd.Parameters.Add(RequestEntityParam);
                    cmd.Parameters.Add(ResponseEntityParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(ShareableProxyParam);

                    cmd.ExecuteNonQuery();
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return resource;
        }

        public static CapabilityGroup CreateCapabilityGroup(CapabilityGroup capabilityGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            resourceGroup.ID = CreateEntityGroup(resourceGroup.Name, resourceGroup.Description, 14, txn, conn);

            if ((autoclose) && (txn != null)) txn.Commit();

            return resourceGroup;
        }

        public static CapabilityGroup GetCapabilityGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceGroup resourceGroup = new ResourceGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                resourceGroup.ID = entityGroup.ID;
                resourceGroup.Name = entityGroup.Name;
                resourceGroup.Description = entityGroup.Description;

                resourceGroup.Resources = ListResourcesByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return resourceGroup;
        }

        public static CapabilityGroup UpdateCapabilityGroup(CapabilityGroup capabilityGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(resourceGroup.ID, resourceGroup.Name, resourceGroup.Description, txn, conn);

                List<ResourceListElement> oldList = ListResourcesByGroup(resourceGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (ResourceListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(resourceGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (resourceGroup.Resources != null)
                {
                    foreach (ResourceListElement newListElement in resourceGroup.Resources)
                    {
                        AssignEntityToEntityGroup(resourceGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return resourceGroup;
        }

        #endregion

        #region type

        public static TypeList ListTypes(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceList list = new ResourceList();
            const string sprocname = "[ServiceEngine].[ListResources]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Resources = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Resources.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static TypeList ListTypesForCapabilities(Guid CapabilityID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceList list = new ResourceList();
            const string sprocname = "[ServiceEngine].[ListResourcesForSystemInstance]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = InstanceID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Resources = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Resources.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<TypeListElement> ListTypesByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<ResourceListElement> list = new List<ResourceListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static Guid CreateType(Type type, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter InstanceIDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDLParam = new SqlParameter("@IDL", SqlDbType.NVarChar);
                    SqlParameter IDLTypeParam = new SqlParameter("@IDLType", SqlDbType.NChar, 100);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter MonikerParam = new SqlParameter("@Moniker", SqlDbType.Xml);
                    SqlParameter RequestEntityParam = new SqlParameter("@RequestEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter ResponseEntityParam = new SqlParameter("@ResponseEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter ShareableProxyParam = new SqlParameter("@ShareableProxy", SqlDbType.Bit);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = resource.Name;
                    DescriptionParam.Value = resource.Description;
                    InstanceIDParam.Value = resource.InstanceID;
                    IDLParam.Value = resource.IDL;
                    IDLTypeParam.Value = resource.IDLType;
                    BindingIDParam.Value = resource.Binding.ID;
                    if (resource.Moniker != null)
                    {
                        MonikerParam.Value = resource.Moniker.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateResource failed: Moniker is a required element but was not sent");
                    }
                    RequestEntityParam.Value = resource.RequestEntityID;
                    ResponseEntityParam.Value = resource.ResponseEntityID;
                    URIParam.Value = resource.URI;
                    ShareableProxyParam.Value = resource.ShareableProxy;
                    if (resource.Policy != null)
                    {
                        PolicyIDParam.Value = resource.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }


                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(InstanceIDParam);
                    cmd.Parameters.Add(IDLParam);
                    cmd.Parameters.Add(IDLTypeParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(MonikerParam);
                    cmd.Parameters.Add(RequestEntityParam);
                    cmd.Parameters.Add(ResponseEntityParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(ShareableProxyParam);


                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static Type GetType(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Resource resource = new Resource();
            const string sprocname = "[ServiceEngine].[GetResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            resource.ID = reader.GetGuid(0);
                            resource.Name = reader.GetString(1);
                            resource.InstanceID = reader.GetGuid(2);
                            if (reader.IsDBNull(3))
                            {
                                resource.IDL = null;
                            }
                            else
                            {
                                resource.IDL = reader.GetString(3);
                            }
                            if (reader.IsDBNull(4))
                            {
                                resource.IDLType = null;
                            }
                            else
                            {
                                resource.IDLType = reader.GetString(4);
                            }

                            resource.Binding = reader.IsDBNull(5) ? null : GetMSEBinding(reader.GetGuid(5), txn, conn);

                            if (reader.IsDBNull(6))
                            {
                                resource.Moniker = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(6).CreateReader());
                                resource.Moniker = xdoc.DocumentElement;
                            }
                            if (reader.IsDBNull(7))
                            {
                                resource.Description = null;
                            }
                            else
                            {
                                resource.Description = reader.GetString(7);
                            }

                            if (!reader.IsDBNull(8))
                            {
                                resource.RequestEntityID = reader.GetGuid(8);
                            }

                            if (!reader.IsDBNull(9))
                            {
                                resource.ResponseEntityID = reader.GetGuid(9);
                            }

                            if (reader.IsDBNull(10))
                            {
                                resource.URI = null;
                            }
                            else
                            {
                                resource.URI = reader.GetString(10);
                            }

                            //TODO may need to get policies from systemInstance and system and create a composite policy
                            resource.Policy = reader.IsDBNull(11) ? null : GetPolicy(reader.GetGuid(11), txn, conn);

                            resource.ShareableProxy = reader.GetBoolean(12);

                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return resource;

        }

        public static void DeleteType(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static Type UpdateType(Type type, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter InstanceIDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDLParam = new SqlParameter("@IDL", SqlDbType.NVarChar);
                    SqlParameter IDLTypeParam = new SqlParameter("@IDLType", SqlDbType.NChar, 100);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter MonikerParam = new SqlParameter("@Moniker", SqlDbType.Xml);
                    SqlParameter RequestEntityParam = new SqlParameter("@RequestEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter ResponseEntityParam = new SqlParameter("@ResponseEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter ShareableProxyParam = new SqlParameter("@ShareableProxy", SqlDbType.Bit);


                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = resource.ID;
                    NameParam.Value = resource.Name;
                    InstanceIDParam.Value = resource.InstanceID;
                    IDLParam.Value = resource.IDL;
                    IDLTypeParam.Value = resource.IDLType;
                    DescriptionParam.Value = resource.Description;
                    BindingIDParam.Value = resource.Binding.ID;
                    if (resource.Moniker != null)
                    {
                        MonikerParam.Value = resource.Moniker.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateResource failed: Moniker is a required element but was not sent");
                    }
                    RequestEntityParam.Value = resource.RequestEntityID;
                    ResponseEntityParam.Value = resource.ResponseEntityID;
                    URIParam.Value = resource.URI;
                    ShareableProxyParam.Value = resource.ShareableProxy;
                    if (resource.Policy != null)
                    {
                        PolicyIDParam.Value = resource.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(InstanceIDParam);
                    cmd.Parameters.Add(IDLParam);
                    cmd.Parameters.Add(IDLTypeParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(MonikerParam);
                    cmd.Parameters.Add(RequestEntityParam);
                    cmd.Parameters.Add(ResponseEntityParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(ShareableProxyParam);

                    cmd.ExecuteNonQuery();
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return resource;
        }

        public static TypeGroup CreateTypeGroup(TypeGroup typeGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            resourceGroup.ID = CreateEntityGroup(resourceGroup.Name, resourceGroup.Description, 14, txn, conn);

            if ((autoclose) && (txn != null)) txn.Commit();

            return resourceGroup;
        }

        public static TypeGroup GetTypeGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceGroup resourceGroup = new ResourceGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                resourceGroup.ID = entityGroup.ID;
                resourceGroup.Name = entityGroup.Name;
                resourceGroup.Description = entityGroup.Description;

                resourceGroup.Resources = ListResourcesByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return resourceGroup;
        }

        public static TypeGroup UpdateTypeGroup(TypeGroup typeGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(resourceGroup.ID, resourceGroup.Name, resourceGroup.Description, txn, conn);

                List<ResourceListElement> oldList = ListResourcesByGroup(resourceGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (ResourceListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(resourceGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (resourceGroup.Resources != null)
                {
                    foreach (ResourceListElement newListElement in resourceGroup.Resources)
                    {
                        AssignEntityToEntityGroup(resourceGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return resourceGroup;
        }

        #endregion

        #region actor

        public static ProcessList ListProcesses(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceList list = new ResourceList();
            const string sprocname = "[ServiceEngine].[ListResources]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.Resources = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.Resources.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<ProcessListElement> ListCapabilitiesByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<ResourceListElement> list = new List<ResourceListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<ResourceListElement>();
                            while (reader.Read())
                            {
                                ResourceListElement element = new ResourceListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static Guid CreateProcess(Process process, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter InstanceIDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDLParam = new SqlParameter("@IDL", SqlDbType.NVarChar);
                    SqlParameter IDLTypeParam = new SqlParameter("@IDLType", SqlDbType.NChar, 100);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter MonikerParam = new SqlParameter("@Moniker", SqlDbType.Xml);
                    SqlParameter RequestEntityParam = new SqlParameter("@RequestEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter ResponseEntityParam = new SqlParameter("@ResponseEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter ShareableProxyParam = new SqlParameter("@ShareableProxy", SqlDbType.Bit);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = resource.Name;
                    DescriptionParam.Value = resource.Description;
                    InstanceIDParam.Value = resource.InstanceID;
                    IDLParam.Value = resource.IDL;
                    IDLTypeParam.Value = resource.IDLType;
                    BindingIDParam.Value = resource.Binding.ID;
                    if (resource.Moniker != null)
                    {
                        MonikerParam.Value = resource.Moniker.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateResource failed: Moniker is a required element but was not sent");
                    }
                    RequestEntityParam.Value = resource.RequestEntityID;
                    ResponseEntityParam.Value = resource.ResponseEntityID;
                    URIParam.Value = resource.URI;
                    ShareableProxyParam.Value = resource.ShareableProxy;
                    if (resource.Policy != null)
                    {
                        PolicyIDParam.Value = resource.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }


                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(InstanceIDParam);
                    cmd.Parameters.Add(IDLParam);
                    cmd.Parameters.Add(IDLTypeParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(MonikerParam);
                    cmd.Parameters.Add(RequestEntityParam);
                    cmd.Parameters.Add(ResponseEntityParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(ShareableProxyParam);


                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static Process GetProcess(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            Resource resource = new Resource();
            const string sprocname = "[ServiceEngine].[GetResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            resource.ID = reader.GetGuid(0);
                            resource.Name = reader.GetString(1);
                            resource.InstanceID = reader.GetGuid(2);
                            if (reader.IsDBNull(3))
                            {
                                resource.IDL = null;
                            }
                            else
                            {
                                resource.IDL = reader.GetString(3);
                            }
                            if (reader.IsDBNull(4))
                            {
                                resource.IDLType = null;
                            }
                            else
                            {
                                resource.IDLType = reader.GetString(4);
                            }

                            resource.Binding = reader.IsDBNull(5) ? null : GetMSEBinding(reader.GetGuid(5), txn, conn);

                            if (reader.IsDBNull(6))
                            {
                                resource.Moniker = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(6).CreateReader());
                                resource.Moniker = xdoc.DocumentElement;
                            }
                            if (reader.IsDBNull(7))
                            {
                                resource.Description = null;
                            }
                            else
                            {
                                resource.Description = reader.GetString(7);
                            }

                            if (!reader.IsDBNull(8))
                            {
                                resource.RequestEntityID = reader.GetGuid(8);
                            }

                            if (!reader.IsDBNull(9))
                            {
                                resource.ResponseEntityID = reader.GetGuid(9);
                            }

                            if (reader.IsDBNull(10))
                            {
                                resource.URI = null;
                            }
                            else
                            {
                                resource.URI = reader.GetString(10);
                            }

                            //TODO may need to get policies from systemInstance and system and create a composite policy
                            resource.Policy = reader.IsDBNull(11) ? null : GetPolicy(reader.GetGuid(11), txn, conn);

                            resource.ShareableProxy = reader.GetBoolean(12);

                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return resource;

        }

        public static void DeleteProcess(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static Process UpdateProcess(Process process, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateResource]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);
                    SqlParameter InstanceIDParam = new SqlParameter("@InstanceID", SqlDbType.UniqueIdentifier);
                    SqlParameter IDLParam = new SqlParameter("@IDL", SqlDbType.NVarChar);
                    SqlParameter IDLTypeParam = new SqlParameter("@IDLType", SqlDbType.NChar, 100);
                    SqlParameter BindingIDParam = new SqlParameter("@BindingID", SqlDbType.UniqueIdentifier);
                    SqlParameter MonikerParam = new SqlParameter("@Moniker", SqlDbType.Xml);
                    SqlParameter RequestEntityParam = new SqlParameter("@RequestEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter ResponseEntityParam = new SqlParameter("@ResponseEntity", SqlDbType.UniqueIdentifier);
                    SqlParameter URIParam = new SqlParameter("@URI", SqlDbType.NVarChar);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);
                    SqlParameter ShareableProxyParam = new SqlParameter("@ShareableProxy", SqlDbType.Bit);


                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = resource.ID;
                    NameParam.Value = resource.Name;
                    InstanceIDParam.Value = resource.InstanceID;
                    IDLParam.Value = resource.IDL;
                    IDLTypeParam.Value = resource.IDLType;
                    DescriptionParam.Value = resource.Description;
                    BindingIDParam.Value = resource.Binding.ID;
                    if (resource.Moniker != null)
                    {
                        MonikerParam.Value = resource.Moniker.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateResource failed: Moniker is a required element but was not sent");
                    }
                    RequestEntityParam.Value = resource.RequestEntityID;
                    ResponseEntityParam.Value = resource.ResponseEntityID;
                    URIParam.Value = resource.URI;
                    ShareableProxyParam.Value = resource.ShareableProxy;
                    if (resource.Policy != null)
                    {
                        PolicyIDParam.Value = resource.Policy.ID;
                    }
                    else
                    {
                        PolicyIDParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(DescriptionParam);
                    cmd.Parameters.Add(InstanceIDParam);
                    cmd.Parameters.Add(IDLParam);
                    cmd.Parameters.Add(IDLTypeParam);
                    cmd.Parameters.Add(BindingIDParam);
                    cmd.Parameters.Add(MonikerParam);
                    cmd.Parameters.Add(RequestEntityParam);
                    cmd.Parameters.Add(ResponseEntityParam);
                    cmd.Parameters.Add(URIParam);
                    cmd.Parameters.Add(PolicyIDParam);
                    cmd.Parameters.Add(ShareableProxyParam);

                    cmd.ExecuteNonQuery();
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return resource;
        }

        public static ProcessGroup CreateProcessGroup(ProcessGroup processGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            resourceGroup.ID = CreateEntityGroup(resourceGroup.Name, resourceGroup.Description, 14, txn, conn);

            if ((autoclose) && (txn != null)) txn.Commit();

            return resourceGroup;
        }

        public static ProcessGroup GetProcessGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            ResourceGroup resourceGroup = new ResourceGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                resourceGroup.ID = entityGroup.ID;
                resourceGroup.Name = entityGroup.Name;
                resourceGroup.Description = entityGroup.Description;

                resourceGroup.Resources = ListResourcesByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return resourceGroup;
        }

        public static ProcessGroup UpdateProcessGroup(ProcessGroup processGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(resourceGroup.ID, resourceGroup.Name, resourceGroup.Description, txn, conn);

                List<ResourceListElement> oldList = ListResourcesByGroup(resourceGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (ResourceListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(resourceGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (resourceGroup.Resources != null)
                {
                    foreach (ResourceListElement newListElement in resourceGroup.Resources)
                    {
                        AssignEntityToEntityGroup(resourceGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return resourceGroup;
        }

        #endregion

        //MSEBinding
        
        public static MSEBindingList ListMSEBindings(SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            MSEBindingList list = new MSEBindingList();
            const string sprocname = "[ServiceEngine].[ListBindings]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list.MSEBindings = new List<MSEBindingListElement>();
                            while (reader.Read())
                            {
                                MSEBindingListElement element = new MSEBindingListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }
                                list.MSEBindings.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }

        public static List<MSEBindingListElement> ListMSEBindingsByGroup(Guid entityGroupID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<MSEBindingListElement> list = new List<MSEBindingListElement>();
            const string sprocname = "[ServiceEngine].[ListEntitiesByGroup]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@entityGroupID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = entityGroupID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            list = new List<MSEBindingListElement>();
                            while (reader.Read())
                            {
                                MSEBindingListElement element = new MSEBindingListElement();
                                element.ID = reader.GetGuid(0);
                                element.Name = reader.GetString(1);
                                if (reader.IsDBNull(2))
                                {
                                    element.Description = null;
                                }
                                else
                                {
                                    element.Description = reader.GetString(2);
                                }

                                list.Add(element);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return list;

        }        

        #region BindingElements
        public static Guid CreateMSEBindingElement(MSEBindingElement bindingElement, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateBindingElement]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter BindingConfigParam = new SqlParameter("@ElementConfig", SqlDbType.Xml);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = bindingElement.Name;
                    if (bindingElement.BindingElementConfig != null)
                    {
                        BindingConfigParam.Value = bindingElement.BindingElementConfig.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("CreateBinding failed: BindingConfig is a required element but was not sent");
                    }
                    if (bindingElement.Description != null)
                    {
                        DescriptionParam.Value = bindingElement.Description;
                    }
                    else
                    {
                        DescriptionParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(BindingConfigParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();

                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static MSEBindingElement UpdateMSEBindingElement(MSEBindingElement binding, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateBindingElement]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                List<DBEventDataItem> eventDataRS = null;
                List<DBEventDataItem> eventDataEP = new List<DBEventDataItem>();
                List<DBEventDataItem> eventDataOP = new List<DBEventDataItem>();
                try
                {
                    //identify where policy is used
                    eventDataRS = DAL.ListRuntimeServersForBindingID(binding.ID, txn, conn);
                    EndpointList epList = DAL.ListEndpointsForBindingID(binding.ID, txn, conn);
                    ChannelList chList = DAL.ListChannelsForBindingID(binding.ID, txn, conn);

                    //get affected runtimes
                    if (epList != null && epList.Endpoints != null)
                    {
                        foreach (EndpointListElement element in epList.Endpoints)
                        {
                            List<DBEventDataItem> temp = DAL.ListRuntimeServersForEndpointID(element.ID, txn, conn);
                            temp.ForEach(item => { if (!eventDataEP.Contains(item)) eventDataEP.Add(item); });
                        }
                    }
                    if (chList != null && chList.Channels != null)
                    {
                        foreach (ChannelListElement element in chList.Channels)
                        {
                            List<DBEventDataItem> temp = DAL.ListRuntimeServersForChannelID(element.ID, txn, conn);
                            temp.ForEach(item => { if (!eventDataOP.Contains(item)) eventDataOP.Add(item); });
                        }
                    }

                    //consolidate eventdata
                    //if EndpointsUpdated event is going to be thrown for an Endpoint, there is no need to throw OperationsUpdated events for the same endpoint
                    //broker will flush cache based on an endpoint being updated
                    if (eventDataEP != null && eventDataEP.Count > 0 && eventDataOP != null && eventDataOP.Count > 0)
                    {
                        foreach (DBEventDataItem epItem in eventDataEP)
                        {
                            for (int i = eventDataOP.Count - 1; i >= 0; i--)
                            {
                                if (epItem.RuntimeServerId == eventDataOP[i].RuntimeServerId && epItem.EndpointId == eventDataOP[i].EndpointId)
                                    eventDataOP.RemoveAt(i);
                            }
                        }
                    }

                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in UpdatePolicy.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }
                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter BindingConfigParam = new SqlParameter("@ElementConfig", SqlDbType.Xml);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = binding.ID;
                    NameParam.Value = binding.Name;
                    if (binding.BindingElementConfig != null)
                    {
                        BindingConfigParam.Value = binding.BindingElementConfig.OuterXml;
                    }
                    else
                    {
                        throw new ApplicationException("UpdateBinding failed: BindingConfig is a required element but was not sent");
                    }
                    if (binding.Description != null)
                    {
                        DescriptionParam.Value = binding.Description;
                    }
                    else
                    {
                        DescriptionParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(BindingConfigParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();
                }

                //send notification to affected runtimes
                RepositoryChangeManager.RecordChange(DBEvents.EndpointsUpdated, DBChangeType.Update, eventDataEP, txn, conn);
                RepositoryChangeManager.RecordChange(DBEvents.OperationsUpdated, DBChangeType.Update, eventDataOP, txn, conn);
                RepositoryChangeManager.RecordChange(DBEvents.RuntimeServersBindingUpdated, DBChangeType.Update, eventDataRS, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return binding;
        }

        public static void DeleteMSEBindingElement(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteBindingElement]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static MSEBindingElement GetMSEBindingElement(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            MSEBindingElement binding = new MSEBindingElement();
            const string sprocname = "[ServiceEngine].[GetBindingElement]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            binding.ID = reader.GetGuid(0);
                            binding.Name = reader.GetString(1);
                            XmlDocument xdoc = new XmlDocument();
                            xdoc.Load(reader.GetSqlXml(2).CreateReader());
                            binding.BindingElementConfig = xdoc.DocumentElement;
                            if (reader.IsDBNull(3))
                            {
                                binding.Description = null;
                            }
                            else
                            {
                                binding.Description = reader.GetString(3);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return binding;

        }

        #endregion

        public static Guid CreateMSEBinding(MSEBinding binding, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateBinding]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    //SqlParameter BindingConfigParam = new SqlParameter("@BindingConfig", SqlDbType.Xml);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Direction = ParameterDirection.Output;
                    NameParam.Value = binding.Name;
                    //if (binding.BindingConfig != null)
                    //{
                    //    BindingConfigParam.Value = binding.BindingConfig.OuterXml;
                    //}
                    //else
                    //{
                    //    throw new ApplicationException("CreateBinding failed: BindingConfig is a required element but was not sent");
                    //}
                    if (binding.Description != null)
                    {
                        DescriptionParam.Value = binding.Description;
                    }
                    else
                    {
                        DescriptionParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    //cmd.Parameters.Add(BindingConfigParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();

                    ID = (Guid)IDParam.Value;
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return ID;
        }

        public static MSEBinding GetMSEBinding(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            MSEBinding binding = new MSEBinding();
            const string sprocname = "[ServiceEngine].[GetBinding]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            binding.ID = reader.GetGuid(0);
                            binding.Name = reader.GetString(1);
                            XmlDocument xdoc = new XmlDocument();
                            xdoc.Load(reader.GetSqlXml(2).CreateReader());
                            binding.BindingConfig = xdoc.DocumentElement;
                            if (reader.IsDBNull(3))
                            {
                                binding.Description = null;
                            }
                            else
                            {
                                binding.Description = reader.GetString(3);
                            }
                        }
                    }
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return binding;

        }
    
        public static void DeleteMSEBinding(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteBinding]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        public static MSEBinding UpdateMSEBinding(MSEBinding binding, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[UpdateBinding]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                #region Change Tracking
                List<DBEventDataItem> eventDataRS = null;
                List<DBEventDataItem> eventDataEP = new List<DBEventDataItem>();
                List<DBEventDataItem> eventDataOP = new List<DBEventDataItem>();
                try
                {
                    //identify where policy is used
                    eventDataRS = DAL.ListRuntimeServersForBindingID(binding.ID, txn, conn);
                    EndpointList epList = DAL.ListEndpointsForBindingID(binding.ID, txn, conn);
                    ChannelList chList = DAL.ListChannelsForBindingID(binding.ID, txn, conn);
                    
                    //get affected runtimes
                    if (epList != null && epList.Endpoints != null)
                    {
                        foreach (EndpointListElement element in epList.Endpoints)
                        {
                            List<DBEventDataItem> temp = DAL.ListRuntimeServersForEndpointID(element.ID, txn, conn);
                            temp.ForEach(item => { if (!eventDataEP.Contains(item)) eventDataEP.Add(item); });
                        }
                    }
                    if (chList != null && chList.Channels != null)
                    {
                        foreach (ChannelListElement element in chList.Channels)
                        {
                            List<DBEventDataItem> temp = DAL.ListRuntimeServersForChannelID(element.ID, txn, conn);
                            temp.ForEach(item => { if (!eventDataOP.Contains(item)) eventDataOP.Add(item); });
                        }
                    }

                    //consolidate eventdata
                    //if EndpointsUpdated event is going to be thrown for an Endpoint, there is no need to throw OperationsUpdated events for the same endpoint
                    //broker will flush cache based on an endpoint being updated
                    if (eventDataEP != null && eventDataEP.Count > 0 && eventDataOP != null && eventDataOP.Count > 0)
                    {
                        foreach (DBEventDataItem epItem in eventDataEP)
                        {
                            for (int i = eventDataOP.Count - 1; i >= 0; i--)
                            {
                                if (epItem.RuntimeServerId == eventDataOP[i].RuntimeServerId && epItem.EndpointId == eventDataOP[i].EndpointId)
                                    eventDataOP.RemoveAt(i);
                            }
                        }
                    }

                }
                catch (System.Exception ex)
                {
                    TraceHelper.TraceError("Error collecting affected runtimes in UpdatePolicy.  No change notifications will be sent. Error [{0}].", DAL.GetExceptionDetails(ex));
                }
                #endregion

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    //SqlParameter BindingConfigParam = new SqlParameter("@BindingConfig", SqlDbType.Xml);
                    SqlParameter DescriptionParam = new SqlParameter("@Description", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = binding.ID;
                    NameParam.Value = binding.Name;
                    //if (binding.BindingConfig != null)
                    //{
                    //    BindingConfigParam.Value = binding.BindingConfig.OuterXml;
                    //}
                    //else
                    //{
                    //    throw new ApplicationException("UpdateBinding failed: BindingConfig is a required element but was not sent");
                    //}
                    if (binding.Description != null)
                    {
                        DescriptionParam.Value = binding.Description;
                    }
                    else
                    {
                        DescriptionParam.Value = DBNull.Value;
                    }

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(NameParam);
                    //cmd.Parameters.Add(BindingConfigParam);
                    cmd.Parameters.Add(DescriptionParam);

                    cmd.ExecuteNonQuery();
                }

                //send notification to affected runtimes
                RepositoryChangeManager.RecordChange(DBEvents.EndpointsUpdated, DBChangeType.Update, eventDataEP, txn, conn);
                RepositoryChangeManager.RecordChange(DBEvents.OperationsUpdated, DBChangeType.Update, eventDataOP, txn, conn);
                RepositoryChangeManager.RecordChange(DBEvents.RuntimeServersBindingUpdated, DBChangeType.Update, eventDataRS, txn, conn);

                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return binding;
        }

        public static MSEBindingGroup CreateMSEBindingGroup(MSEBindingGroup mseBindingGroup, SqlTransaction txn, SqlConnection conn)
        {

            bool autoclose = false;

            if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

            mseBindingGroup.ID = CreateEntityGroup(mseBindingGroup.Name, mseBindingGroup.Description, 6, txn, conn);

            if (mseBindingGroup.MSEBindings != null)
            {
                foreach (MSEBindingListElement mseBinding in mseBindingGroup.MSEBindings)
                {
                    AssignEntityToEntityGroup(mseBindingGroup.ID, mseBinding.ID, txn, conn);
                }
            }

            if ((autoclose) && (txn != null)) txn.Commit();

            return mseBindingGroup;
        }

        public static MSEBindingGroup GetMSEBindingGroup(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            MSEBindingGroup mseBindingGroup = new MSEBindingGroup();
            EntityGroup entityGroup = new EntityGroup();

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                entityGroup = GetEntityGroup(ID, txn, conn);

                mseBindingGroup.ID = entityGroup.ID;
                mseBindingGroup.Name = entityGroup.Name;
                mseBindingGroup.Description = entityGroup.Description;

                mseBindingGroup.MSEBindings = ListMSEBindingsByGroup(ID, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return mseBindingGroup;
        }

        public static MSEBindingGroup UpdateMSEBindingGroup(MSEBindingGroup mseBindingGroup, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (txn == null) txn = conn.BeginTransaction(IsolationLevel.Snapshot);

                ID = UpdateEntityGroup(mseBindingGroup.ID, mseBindingGroup.Name, mseBindingGroup.Description, txn, conn);


                List<MSEBindingListElement> oldList = ListMSEBindingsByGroup(mseBindingGroup.ID, txn, conn);
                /// Delete all items from the old list
                if (oldList != null)
                {
                    foreach (MSEBindingListElement oldListElement in oldList)
                    {
                        RemoveEntityFromEntityGroup(mseBindingGroup.ID, oldListElement.ID, txn, conn);
                    }
                }
                /// Add all items from the new list
                if (mseBindingGroup.MSEBindings != null)
                {
                    foreach (MSEBindingListElement newListElement in mseBindingGroup.MSEBindings)
                    {
                        AssignEntityToEntityGroup(mseBindingGroup.ID, newListElement.ID, txn, conn);
                    }
                }
                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }

            return mseBindingGroup;
        }

        public static List<OperationVersion> GetOperationVersionsForEndpointAndAction(Guid endpointID, string action, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<OperationVersion> response = new List<OperationVersion>();
            const string sprocname = "[ServiceEngine].[GetOperationVersionsForEndpointAndAction]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);
                    SqlParameter OperationNameParam = new SqlParameter("@OperationName", SqlDbType.NVarChar, 4000);
                    SqlParameter VersionMajorParam = new SqlParameter("@VersionMajor", SqlDbType.Int);
                    SqlParameter VersionMinorParam = new SqlParameter("@VersionMinor", SqlDbType.Int);
                    SqlParameter VersionBuildParam = new SqlParameter("@VersionBuild", SqlDbType.Int);
                    SqlParameter VersionQFEParam = new SqlParameter("@VersionQFE", SqlDbType.Int);

                    cmd.CommandType = CommandType.StoredProcedure;
                    EndpointIDParam.Value = endpointID;
                    OperationNameParam.Value = DBNull.Value;
                    VersionMajorParam.Value = DBNull.Value;
                    VersionMinorParam.Value = DBNull.Value;
                    VersionBuildParam.Value = DBNull.Value;
                    VersionQFEParam.Value = DBNull.Value;

                    // Parse Action into subfields
                    if (!string.IsNullOrEmpty(action))
                    {
                        string[] tokens = action.Split(new char[] { ':' });
                        if (tokens.Length > 2) throw new ApplicationException(string.Format("GetOperationVersionsForEndpointAndAction failed to parse Action [{0}].  Expected no more than two sections, found [{1}]", action, tokens.Length));
                        if (tokens.Length == 1)
                        { // Endpoint and Operation Name
                            OperationNameParam.Value = tokens[0];
                            VersionMajorParam.Value = DBNull.Value;
                            VersionMinorParam.Value = DBNull.Value;
                            VersionBuildParam.Value = DBNull.Value;
                            VersionQFEParam.Value = DBNull.Value;
                        }
                        else
                        {
                            if (tokens.Length == 2)
                            { // Endpoint, Operation Name and Version
                                OperationNameParam.Value = tokens[0];
                                SetVersionParams(tokens[1], VersionMajorParam, VersionMinorParam, VersionBuildParam, VersionQFEParam);
                            }
                        }
                    }

                    cmd.Parameters.Add(EndpointIDParam);
                    cmd.Parameters.Add(OperationNameParam);
                    cmd.Parameters.Add(VersionMajorParam);
                    cmd.Parameters.Add(VersionMinorParam);
                    cmd.Parameters.Add(VersionBuildParam);
                    cmd.Parameters.Add(VersionQFEParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            OperationVersion version = new OperationVersion();

                            version.ID = reader.GetGuid(0);
                            VersionNumber verNumber = new VersionNumber();
                            verNumber.Major = reader.GetInt32(1).ToString();
                            verNumber.Minor = reader.GetInt32(2).ToString();
                            verNumber.Build = reader.GetInt32(3).ToString();
                            verNumber.Qfe = reader.GetInt32(4).ToString();
                            version.Version = verNumber;
                            if (reader.IsDBNull(5))
                            {
                                version.AutoResponse = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(5).CreateReader());
                                version.AutoResponse = xdoc.DocumentElement;

                            }
                            //rcamacho - version.OperationName was missing
                            version.OperationName = OperationNameParam.Value.ToString();
                            version.IsTestable = reader.GetBoolean(6);
                            version.IsActive = reader.GetBoolean(7);
                            version.RequestMsg = GetMessage(version.ID, SC.IsRequestMsg, txn, conn);
                            version.ResponseMsg = GetMessage(version.ID, SC.IsResponseMsg, txn, conn);

                            if (reader.IsDBNull(8))
                            {
                                version.RequestTransformXSLT = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(8).CreateReader());
                                version.RequestTransformXSLT = xdoc.DocumentElement;
                            }

                            if (reader.IsDBNull(9))
                            {
                                version.ResponseTransformXSLT = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(9).CreateReader());
                                version.ResponseTransformXSLT = xdoc.DocumentElement;
                            }

                            if (reader.IsDBNull(12))
                            {
                                version.Resource = null;
                            }
                            else
                            {
                                Resource res = GetResource(reader.GetGuid(12), txn, conn);
                                version.Resource = res;
                            }

                            version.OperationID = reader.GetGuid(11);
                            // Get SoapFaults
                            version.SoapFaults = GetSoapFaults(version.ID, txn, conn);
                            response.Add(version);
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            if (response.Count == 0)
            {
                throw new ApplicationException(string.Format("No Active Operations exist on this endpoint that are identified by the Action parameter {0}", action));
            }

            return response;

        }

        private static void SetVersionParams(string versionString, SqlParameter VersionMajorParam, SqlParameter VersionMinorParam, SqlParameter VersionBuildParam, SqlParameter VersionQFEParam)
        {
            string[] versionNodes = versionString.Split(new char[] { '.' });

            try
            {
                if (versionNodes.Length > 0) VersionMajorParam.Value = int.Parse(versionNodes[0]);
                if (versionNodes.Length > 1) VersionMinorParam.Value = int.Parse(versionNodes[1]);
                if (versionNodes.Length > 2) VersionBuildParam.Value = int.Parse(versionNodes[2]);
                if (versionNodes.Length > 3) VersionQFEParam.Value = int.Parse(versionNodes[3]);
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Attempt to parse version number from Action failed: " + ex.Message);
            }
        }

        public static List<OperationVersion> GetOperationVersionsForEndpointAndFirstBodyElement(Guid endpointID, string elementName, string namespaceURI, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<OperationVersion> response = new List<OperationVersion>();
            const string sprocname = "[ServiceEngine].[GetOperationVersionsForEndpointAndFirstBodyElement]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);
                    SqlParameter ElementNameParam = new SqlParameter("@ElementName", SqlDbType.NVarChar, 400);
                    SqlParameter namespaceURIParam = new SqlParameter("@namespaceURI", SqlDbType.NText);

                    cmd.CommandType = CommandType.StoredProcedure;
                    EndpointIDParam.Value = endpointID;
                    ElementNameParam.Value = elementName;
                    namespaceURIParam.Value = namespaceURI;

                    cmd.Parameters.Add(EndpointIDParam);
                    cmd.Parameters.Add(ElementNameParam);
                    cmd.Parameters.Add(namespaceURIParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            OperationVersion version = new OperationVersion();
                            version.ID = reader.GetGuid(0);
                            VersionNumber verNumber = new VersionNumber();
                            verNumber.Major = reader.GetInt32(1).ToString();
                            verNumber.Minor = reader.GetInt32(2).ToString();
                            verNumber.Build = reader.GetInt32(3).ToString();
                            verNumber.Qfe = reader.GetInt32(4).ToString();
                            version.Version = verNumber;
                            if (reader.IsDBNull(5))
                            {
                                version.AutoResponse = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(5).CreateReader());
                                version.AutoResponse = xdoc.DocumentElement;

                            }
                            version.IsTestable = reader.GetBoolean(6);
                            version.IsActive = reader.GetBoolean(7);
                            version.RequestMsg = GetMessage(version.ID, SC.IsRequestMsg, txn, conn);
                            version.ResponseMsg = GetMessage(version.ID, SC.IsResponseMsg, txn, conn);

                            if (reader.IsDBNull(8))
                            {
                                version.RequestTransformXSLT = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(8).CreateReader());
                                version.RequestTransformXSLT = xdoc.DocumentElement;
                            }

                            if (reader.IsDBNull(9))
                            {
                                version.ResponseTransformXSLT = null;
                            }
                            else
                            {
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(9).CreateReader());
                                version.ResponseTransformXSLT = xdoc.DocumentElement;
                            }

                            if (reader.IsDBNull(12))
                            {
                                version.Resource = null;
                            }
                            else
                            {
                                Resource res = GetResource(reader.GetGuid(12), txn, conn);
                                version.Resource = res;
                            }

                            version.OperationID = reader.GetGuid(11);
                            // Get SoapFaults
                            version.SoapFaults = GetSoapFaults(version.ID, txn, conn);
                            response.Add(version);
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            if (response.Count == 0)
            {
                throw new ApplicationException(string.Format("No Active Operations exist on this endpoint with the first body element of {0} in namespace {1}", elementName, namespaceURI));
            }

            return response;

        }

        public static void PublishRuntimeServerEndPointsToUddi(Guid runtimeServerID, bool refresh, SqlTransaction txn, SqlConnection conn)
        {
            if (Configurator.svcConfig.serviceCatalogUddi == null ||
                Configurator.svcConfig.serviceCatalogUddi.UddiIntegrationMode == false)
                return;

            RuntimeServer runtimeServer = GetRuntimeServer(runtimeServerID, false, txn, conn);

            if (runtimeServer.Endpoints != null && runtimeServer.Endpoints.Count > 0)
            {
                foreach (Endpoint endpint in runtimeServer.Endpoints)
                {
                    PublishEndPointToUddi(endpint, runtimeServer, refresh, txn, conn);
                }
            }
        }

        public static void RemoveRuntimeServerEndPointsFromUddi(Guid runtimeServerID, SqlTransaction txn, SqlConnection conn)
        {
            if (Configurator.svcConfig.serviceCatalogUddi == null ||
                Configurator.svcConfig.serviceCatalogUddi.UddiIntegrationMode == false)
                return;

            RuntimeServer runtimeServer = GetRuntimeServer(runtimeServerID, false, txn, conn);

            if (runtimeServer.Endpoints != null && runtimeServer.Endpoints.Count > 0)
            {
                foreach (Endpoint endpint in runtimeServer.Endpoints)
                {
                    RemoveEndPointFromUddi(endpint,runtimeServer, txn, conn);
                }
            }
        }

        private static void PublishEndPointToUddi(Endpoint endpoint, RuntimeServer runtimeServer, bool refresh, SqlTransaction txn, SqlConnection conn)
        {
            if (Configurator.svcConfig.serviceCatalogUddi == null ||
                Configurator.svcConfig.serviceCatalogUddi.UddiIntegrationMode == false)
                return;

            bool autoclose = false;

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                if (refresh == true)
                {
                    RemoveEndPointFromUddi(endpoint, runtimeServer, txn, conn);
                }

                // Check if the Endpoint is valid for publishing
                if (endpoint.PubOpVersionsList != null &&
                    endpoint.PubOpVersionsList.OperationVersions != null &&
                    endpoint.PubOpVersionsList.OperationVersions.Count > 0 )
                {
                    bool isUpdate = false;
                    bool isNew = false;

                    EndpointAssociatedUddi endpointAssociatedUddi = GetUddiAssociation(endpoint, runtimeServer);
                    if (endpointAssociatedUddi != null
                            && String.IsNullOrEmpty(endpointAssociatedUddi.ServiceKey) == false
                            && String.IsNullOrEmpty(endpointAssociatedUddi.BindingKey) == false
                            && String.IsNullOrEmpty(endpointAssociatedUddi.TModelKey) == false)
                    {
                        // Update only if anything has changed
                        Uri serviceUri = GetEndpointServiceUri(endpoint, runtimeServer);
                        if (string.Compare(serviceUri.ToString(), endpointAssociatedUddi.BindingUrl, true) != 0)
                        {
                            isUpdate = true;
                        }
                    }
                    else
                    {
                        isNew = true;
                    }
                    if (isUpdate || isNew)
                    {
                        // Publish the Endpoint to UDDI
                        using (UddiPublisher uddiPublisher = new UddiPublisher(Configurator.svcConfig.serviceCatalogUddi))
                        {
                            if (isUpdate)
                            {
                                endpoint = uddiPublisher.UpdateEndpointToUddi(endpoint,runtimeServer);
                            }
                            if (isNew)
                            {
                                endpoint = uddiPublisher.PublishEndpointToUddi(endpoint, runtimeServer);
                            }
                        }
                        // Get the newly created or updates association
                        endpointAssociatedUddi = GetUddiAssociation(endpoint, runtimeServer);
                        string procName = "";
                        if (isUpdate)
                            procName = "[ServiceEngine].[UpdateEndpointUddiAssociation]";
                        else
                            procName = "[ServiceEngine].[CreateEndpointUddiAssociation]";
                        // Add the association to database
                        using (SqlCommand cmd = new SqlCommand(procName, conn, txn))
                        {
                            SqlParameter ServiceKeyParam = null;
                            SqlParameter TModelKeyParam = null;
                            SqlParameter BindingKeyParam = null;
                            if (isUpdate == false)
                            {
                                ServiceKeyParam = new SqlParameter("@ServiceKey", SqlDbType.NVarChar, 64);
                                TModelKeyParam = new SqlParameter("@TModelKey", SqlDbType.NVarChar, 64);
                                BindingKeyParam = new SqlParameter("@BindingKey", SqlDbType.NVarChar, 64);
                            }
                            SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);
                            SqlParameter RuntimeServerIDParam = new SqlParameter("@RuntimeServerID", SqlDbType.UniqueIdentifier);
                            SqlParameter WsdlUrlParam = new SqlParameter("@WsdlUrl", SqlDbType.NVarChar, 400);
                            SqlParameter BindingUrlParam = new SqlParameter("@BindingUrl", SqlDbType.NVarChar, 400);

                            cmd.CommandType = CommandType.StoredProcedure;

                            if (isUpdate == false)
                            {
                                ServiceKeyParam.Value = endpointAssociatedUddi.ServiceKey;
                                TModelKeyParam.Value = endpointAssociatedUddi.TModelKey;
                                BindingKeyParam.Value = endpointAssociatedUddi.BindingKey;
                            }
                            EndpointIDParam.Value = endpoint.ID;
                            RuntimeServerIDParam.Value = runtimeServer.ID;
                            WsdlUrlParam.Value = endpointAssociatedUddi.WsdlUrl;
                            BindingUrlParam.Value = endpointAssociatedUddi.BindingUrl;

                            if (isUpdate == false)
                            {
                                cmd.Parameters.Add(ServiceKeyParam);
                                cmd.Parameters.Add(TModelKeyParam);
                                cmd.Parameters.Add(BindingKeyParam);
                            }
                            cmd.Parameters.Add(EndpointIDParam);
                            cmd.Parameters.Add(RuntimeServerIDParam);
                            cmd.Parameters.Add(WsdlUrlParam);
                            cmd.Parameters.Add(BindingUrlParam);

                            cmd.ExecuteNonQuery();
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }
        }

        private static void PublishEndPointToUddi(Guid endpointID, Guid runtimeServerID, bool refresh, SqlTransaction txn, SqlConnection conn)
        {
            if (Configurator.svcConfig.serviceCatalogUddi == null ||
                Configurator.svcConfig.serviceCatalogUddi.UddiIntegrationMode == false)
                return;

            bool autoclose = false;

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                Endpoint endPoint = GetEndpoint(endpointID, runtimeServerID, false, txn, conn);
                RuntimeServer runtimeServer = GetRuntimeServer(runtimeServerID, false, txn, conn);
                PublishEndPointToUddi(endPoint, runtimeServer, refresh, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }
        }

        private static void RemoveEndPointFromUddi(Endpoint endpoint, RuntimeServer runtimeServer, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[RemoveEndpointUddiAssociation]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                // Remove the Endpoint from UDDI
                if (Configurator.svcConfig.serviceCatalogUddi != null &&
                    Configurator.svcConfig.serviceCatalogUddi.UddiIntegrationMode == true)
                {
                    using (UddiPublisher uddiPublisher = new UddiPublisher(Configurator.svcConfig.serviceCatalogUddi))
                    {
                        uddiPublisher.RemoveEndpointFromUddi(endpoint,runtimeServer );
                    }
                }
                // Remove the Endpoint association from Database
                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter EndpointIDParam = new SqlParameter("@EndpointID", SqlDbType.UniqueIdentifier);
                    SqlParameter RuntimeServerIDParam = new SqlParameter("@RuntimeServerID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    EndpointIDParam.Value = endpoint.ID;
                    RuntimeServerIDParam.Value = runtimeServer.ID; 

                    cmd.Parameters.Add(EndpointIDParam);
                    cmd.Parameters.Add(RuntimeServerIDParam);
                    cmd.ExecuteNonQuery();

                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }
        }

        private static void RemoveEndPointFromUddi(Guid endpointID, Guid runtimeServerID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[RemoveEndpointUddiAssociation]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                Endpoint endPoint = GetEndpoint(endpointID, runtimeServerID, false, txn, conn);
                RuntimeServer runtimeServer = GetRuntimeServer(runtimeServerID, false, txn, conn);
                RemoveEndPointFromUddi(endPoint, runtimeServer, txn, conn);
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }
        }

        internal static EndpointAssociatedUddi GetUddiAssociation(Endpoint endPoint, RuntimeServer runtimeServer)
        {
            EndpointAssociatedUddi endpointAssociatedUddi = null;

            if (endPoint.UddiAssociations != null && endPoint.UddiAssociations.Count > 0)
            {
                foreach (EndpointAssociatedUddi eua in endPoint.UddiAssociations)
                {
                    if (eua.EndpointID.CompareTo(endPoint.ID) == 0 &&
                        eua.RuntimeServerID.CompareTo(runtimeServer.ID) == 0)
                    {
                        endpointAssociatedUddi = eua;
                        break;
                    }
                }
            }
            return endpointAssociatedUddi;
        }

        private static string[] BuildOperationNameArray(List<OperationListElement> operations)
        {
            string[] operationNames = null;
            if (operations.Count > 0)
            {
                operationNames = new string[operations.Count];
                int counter = 0;
                foreach (OperationListElement operation in operations)
                {
                    operationNames[counter] = operation.Name;
                    counter++;
                }
            }
            return operationNames;
        }
        
        public static string GetExceptionDetails(Exception ex)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Exception Information Type[{0}] Message[{1}] ", ex.GetType().Name, ex.Message);
            Exception iex = ex.InnerException;
            while (iex != null)
            {
                sb.AppendFormat("Inner Exception Information Type[{0}] Message[{1}] ", iex.GetType().Name, iex.Message);
                iex = iex.InnerException;
            }
            return sb.ToString();
        }

        private static string RemoveUriScheme(string endPointUri)
        {
            if (endPointUri.IndexOf("://") > -1)
            {
                endPointUri = endPointUri.Substring(endPointUri.IndexOf("://") + 3);
            }
            return endPointUri;
        }

        public static void AppendImportElementToSchema(XmlDocument schema, XmlNode nxl)
        {
            bool found = false;
            XmlNamespaceManager xmlns = new XmlNamespaceManager(schema.NameTable);
            xmlns.AddNamespace("xsd", XmlSchema.Namespace);
            XmlNodeList importNodes = schema.SelectNodes("//xsd:import", xmlns);
            foreach (XmlNode xn in importNodes)
            {
                string name1 = null;
                string name2 = null;
                if (xn.Attributes["namespace"] != null) name1 = xn.Attributes["namespace"].Value;
                if (nxl.Attributes["namespace"] != null) name2 = nxl.Attributes["namespace"].Value;
                if ((!string.IsNullOrEmpty(name1)) && (!string.IsNullOrEmpty(name2)) && (name1.Equals(name2) == true))
                {
                    found = true;
                }
            }
            if (found == false)
            {
                // import does not exist so just add
                schema.DocumentElement.InsertBefore(nxl, schema.DocumentElement.FirstChild);
            }
        }

        //SGK
        public static void AssignEntityPolicy(Guid entityID, Guid policyID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[AssignEntityPolicy]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter EntityIDParam = new SqlParameter("@EntityID", SqlDbType.UniqueIdentifier);
                    SqlParameter PolicyIDParam = new SqlParameter("@PolicyID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    EntityIDParam.Value = entityID;
                    cmd.Parameters.Add(EntityIDParam);
                    PolicyIDParam.Value = policyID;
                    cmd.Parameters.Add(PolicyIDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        //SGK
        private static void DeletePoliciesFromEntity(Guid entityID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeletePoliciesFromEntity]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter EntityIDParam = new SqlParameter("@EntityID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    EntityIDParam.Value = entityID;
                    cmd.Parameters.Add(EntityIDParam);

                    cmd.ExecuteNonQuery();
                }

                if ((autoclose) && (txn != null)) txn.Commit();
            }
            catch (Exception)
            {
                if (txn != null) try { if (txn != null) txn.Rollback(); }
                    catch (InvalidOperationException) { };
                throw;
            }
            finally
            {
                if (autoclose) { try { conn.Close(); } catch (InvalidOperationException) { };}
            }
        }

        //SGK
        public static Policy[] GetEntityPolicies(Guid entityID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<Policy> polList = null;
            Policy[] arrPol = null;
            const string sprocname = "[ServiceEngine].[GetEntityPolicies]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    SqlParameter EntityIDParam = new SqlParameter("@EntityID", SqlDbType.UniqueIdentifier);
                    EntityIDParam.Value = entityID;
                    cmd.Parameters.Add(EntityIDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            polList = new List<Policy>();
                            while (reader.Read())
                            {
                                polList.Add(GetPolicy(reader.GetGuid(0), txn, conn));
                            }
                        }
                    }
                }

                if (polList != null)
                {
                    arrPol = new Policy[polList.Count];
                    for (int i = 0; i < polList.Count; i++)
                    {
                        arrPol[i] = polList[i];
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return arrPol;
        }
        
        private static bool IsGuidNullOrEmpty(string id)
        {
            if (string.IsNullOrEmpty(id))
                return true;
            try
            {
                Guid guidId = new Guid(id);
                if (Guid.Empty == guidId)
                    return true;
            }
            catch { return true; }
            return false;
        }

        public static void LogRepositoryChange(string xmlMessage, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[QueueRepositoryChange]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    SqlParameter MessageParam = new SqlParameter("@Message", SqlDbType.Xml);
                    MessageParam.Value = @xmlMessage;
                    cmd.Parameters.Add(MessageParam);

                    cmd.ExecuteNonQuery();
                }

            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }
        }

        #region Functions for Extracting Relevant Types from the Schema
        /// <summary>
        /// 
        /// </summary>
        /// <param name="operationVersions"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        /// <returns></returns>
        private static Dictionary<string, XmlSchema> ExtractRelevantSchemaTypes(List<OperationVersion> operationVersions,
                                                                                SqlTransaction txn, SqlConnection conn)
        {
            Dictionary<string, XmlSchema> relevantSchemaHash = new Dictionary<string, XmlSchema>();
            Dictionary<Guid, string> mappedElemntHash = new Dictionary<Guid, string>();

            try
            {
                foreach (OperationVersion operationVersion in operationVersions)
                {
                    if (operationVersion.RequestMsg != null)
                    {
                        foreach (MessagePart messagePart in operationVersion.RequestMsg)
                        {
                            SchemaObject schemaObject = GetSchemaObjectByNameTypeAndNamespace(messagePart.NamespaceURI,messagePart.ElementName,SchemaObjectType.Element,txn,conn);
                            if (AddTypeToSchemaAndHash(schemaObject, relevantSchemaHash, mappedElemntHash) == false)
                            {
                                AddDependenciesToSchema(schemaObject, relevantSchemaHash, mappedElemntHash, txn, conn);
                            }
                        }
                    }
                    if (operationVersion.ResponseMsg != null)
                    {
                        foreach (MessagePart messagePart in operationVersion.ResponseMsg)
                        {
                            SchemaObject schemaObject = GetSchemaObjectByNameTypeAndNamespace(messagePart.NamespaceURI,messagePart.ElementName,SchemaObjectType.Element,txn,conn);
                            if (AddTypeToSchemaAndHash(schemaObject, relevantSchemaHash, mappedElemntHash) == false)
                            {
                                AddDependenciesToSchema(schemaObject, relevantSchemaHash, mappedElemntHash, txn, conn);
                            }
                        }
                    }
                    if (operationVersion.SoapFaults != null)
                    {
                        foreach (SoapFault soapFault in operationVersion.SoapFaults)
                        {
                            SchemaObject schemaObject = GetSchemaObjectByNameTypeAndNamespace(soapFault.NamespaceURI, soapFault.ElementName, SchemaObjectType.Element, txn, conn);
                            if (AddTypeToSchemaAndHash(schemaObject, relevantSchemaHash, mappedElemntHash) == false)
                            {
                                AddDependenciesToSchema(schemaObject, relevantSchemaHash, mappedElemntHash, txn, conn);
                            }
                        }
                    }
                }
                // Make sure that this schema set can be compiled
                XmlSchemaSet xssRelevant = new XmlSchemaSet();
                foreach (XmlSchema xsRelevant in relevantSchemaHash.Values)
                {
                    xssRelevant.Add(xsRelevant);
                    //string schemaXml = SerializeSchema(xsRelevant);
                }
                xssRelevant.Compile();
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("Failed to extrat relevant schema types due to error [{0}]", GetExceptionDetails(ex)),ex);
            }
            return relevantSchemaHash;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="schemaObject"></param>
        /// <param name="schemaHash"></param>
        /// <param name="mappedTypeHash"></param>
        private static void AddDependenciesToSchema(SchemaObject schemaObject, Dictionary<string, XmlSchema> schemaHash,
                                                    Dictionary<Guid, string> mappedTypeHash, SqlTransaction txn, SqlConnection conn)
        {
            List<SchemaObject> dependencies = ListSchemaObjectDependencies(schemaObject.ID,null,null);
            if (dependencies.Count > 0)
            {
                foreach (SchemaObject key in dependencies)
                {
                    if (AddTypeToSchemaAndHash(key, schemaHash, mappedTypeHash) == false)
                    {
                        AddDependenciesToSchema(key, schemaHash, mappedTypeHash,txn,conn);
                    }
                }
            }
        }


        private static XmlSchema GetSchemaFromMap(Dictionary<string, XmlSchema> schemaHash, string schemaNamepsace)
        {
            XmlSchema xs = null;
            if (schemaHash.ContainsKey(schemaNamepsace) == false)
            {
                xs = new XmlSchema();
                xs.TargetNamespace = schemaNamepsace;
                xs.ElementFormDefault = XmlSchemaForm.Qualified;
                schemaHash.Add(schemaNamepsace, xs);
            }
            else
            {
                xs = schemaHash[schemaNamepsace];
            }
            return xs;
        }

        private static XmlSchemaAttributeGroup GetAttributeFromSchmea(XmlSchemaSet schemaSet, XmlQualifiedName qualifiedName)
        {
            ICollection schemas = schemaSet.Schemas();
            XmlSchemaAttributeGroup xsag = null;
            foreach (XmlSchema schema in schemas)
            {
                if (string.Compare(schema.TargetNamespace, qualifiedName.Namespace, true) == 0)
                {
                    xsag = (XmlSchemaAttributeGroup)schema.AttributeGroups[qualifiedName];
                }
            }
            return xsag;
        }

        private static XmlDocument ConverXmlSchemaToDOM(XmlSchema xmlSchema)
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(SerializeSchema(xmlSchema));
            return xmlDocument;
        }
        private static string SerializeSchema(XmlSchema xmlSchema)
        {
            StringBuilder sb = new StringBuilder();
            XmlWriter xw = XmlWriter.Create(sb);
            xmlSchema.Write(xw);
            xw.Flush();
            return sb.ToString();
        }

        #endregion

        #region Functions for Updated Metadata Builder with ServiceDescription
        /// <summary>
        /// Creates a WSDL from the metadata information stored in the service catalog
        /// </summary>
        /// <param name="endpoint"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        /// <returns></returns>
        private static XmlElement CreateWSDLFromEndpointMetadata(Endpoint endpoint, SqlTransaction txn, SqlConnection conn)
        {
            XmlElement wsdlElement = null;
            OperationVersionList publishedOpVers = DAL.ListPublishedOperationsForEndpoint(endpoint.ID, null, null);
            if (publishedOpVers.OperationVersions != null && publishedOpVers.OperationVersions.Count > 0)
            {
                // Load all the operation versions
                List<OperationVersion> operationVersions = LoadAllOperationVersions(publishedOpVers, txn, conn);

                // Load all the relevant schmeas objects
                Dictionary<string, XmlSchema> schemaHash = ExtractRelevantSchemaTypes(operationVersions, txn, conn);

                WCF.Binding mseBinding = null;
                WSDL.ServiceDescription serviceDescription = null;

                string virtualServiceName = "", serviceNamespace = "";
                Uri serviceUri = null;
                serviceNamespace = CreateServiceInformation(endpoint, ref virtualServiceName, ref serviceUri,ref mseBinding);

                // Create the wsdl:types section of the WSDL from schemas in the repository
                serviceDescription = CreateServiceDesciptionFromSchemas(schemaHash, operationVersions, serviceNamespace, txn, conn);

                // Create the wsdl:message, wsdl:portTypes and wsdl:port sections of the WSDL
                AppendContractToServiceDescription(serviceDescription, endpoint, serviceUri, publishedOpVers,mseBinding, txn, conn);

                // Convert the WSDL into an XML documnet ans return the top level element
                XmlDocument metadataDocument = new XmlDocument();
                string metadataXml = ConvertWSDLToString(serviceDescription);
                metadataDocument.LoadXml(metadataXml.ToString());
                wsdlElement = metadataDocument.DocumentElement;
            }
            return wsdlElement;
        }
        /// <summary>
        /// Loads all the operation versions from the service catalog
        /// </summary>
        /// <param name="publishedOpVers"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        /// <returns></returns>
        private static List<OperationVersion> LoadAllOperationVersions(OperationVersionList publishedOpVers, SqlTransaction txn, SqlConnection conn)
        {
            List<OperationVersion> operationVersions = new List<OperationVersion>();
            foreach (OperationVersionListElement ovle in publishedOpVers.OperationVersions)
            {
                operationVersions.Add(GetOperationVersion(ovle.ID,txn,conn));
            }
            return operationVersions;
        }
        /// <summary>
        /// Loads all the relevant schemas from the service catalog
        /// </summary>
        /// <param name="endpoint"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        /// <returns></returns>
        private static Dictionary<string, XmlSchema> LoadAllSchemasForEndpoint(Endpoint endpoint, SqlTransaction txn, SqlConnection conn)
        {
            XmlSchemaSet xss = new XmlSchemaSet();
            Dictionary<string, XmlSchema> schemaHash = new Dictionary<string, XmlSchema>();

            List<Schema> schemaList = ListSchemasForEndpoint(endpoint.ID, txn, conn);
            if (schemaList != null && schemaList.Count > 0)
            {
                foreach (Schema schema in schemaList)
                {
                    if (schemaHash.ContainsKey(schema.NamespaceURI) == false)
                    {
                        XmlSchema xs = LoadXmlSchemaFromString(schema.XSD.OuterXml);
                        schemaHash.Add(xs.TargetNamespace,xs);
                    }
                }
            }
            return schemaHash;
        }
        /// <summary>
        /// Creates the wsdl:types section of the WSDL using the schemas associated with the published operation
        /// </summary>
        /// <param name="endpoint"></param>
        /// <param name="serviceNamespace"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        /// <returns></returns>
        private static WSDL.ServiceDescription CreateServiceDesciptionFromSchemas(Dictionary<string, XmlSchema> schemaHash, List<OperationVersion> operationVersions, string serviceNamespace, SqlTransaction txn, SqlConnection conn)
        {

            WSDL.ServiceDescription serviceDescription = new System.Web.Services.Description.ServiceDescription();

            // Validate Schemas
            try
            {
                XmlSchemaSet xss = new XmlSchemaSet();
                foreach (XmlSchema xs in schemaHash.Values)
                {
                    xss.Add(xs);
                }
                xss.Compile();
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("Failed to validate schemas as schema set compilation failed due to error [{0}]", GetExceptionDetails(ex)));
            }

            foreach (XmlSchema xs in schemaHash.Values)
            {
                serviceDescription.Types.Schemas.Add(xs);
            }

            // We need to assign a targetnamespace to the WSDL
            // Assigning it using the object model i.e. serviceDescription.TargetNamespace cause the WSDL to loose all the namespaces 
            // that it has while we assigned types (schemas) to it
            string data = ConvertWSDLToString(serviceDescription);
            
            XmlDocument xdoc = new XmlDocument();
            xdoc.LoadXml(data);
            XmlAttribute xat = xdoc.CreateAttribute("xmlns:tns");
            xat.Value = serviceNamespace;
            xdoc.DocumentElement.Attributes.Append(xat);

            xat = xdoc.CreateAttribute("targetNamespace");
            xat.Value = serviceNamespace;
            xdoc.DocumentElement.Attributes.Append(xat);

            serviceDescription = WSDL.ServiceDescription.Read(new StringReader(xdoc.OuterXml));
            return serviceDescription;
        }
        /// <summary>
        /// Creates the wsdl:message, wsdl:portTypes and wsdl:port sections of the WSDL based upon the metadata available in the ServiceCatalog
        /// Please note that this WSDL will be merged with the WSDL generated by Runtime to get the final WSDL that has all the type and policy 
        /// information.
        /// </summary>
        /// <param name="serviceDescription"></param>
        /// <param name="endpoint"></param>
        /// <param name="serviceUri"></param>
        /// <param name="publishedOpVers"></param>
        /// <param name="mseBinding"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        private static void AppendContractToServiceDescription(WSDL.ServiceDescription serviceDescription,Endpoint endpoint, Uri serviceUri, OperationVersionList publishedOpVers, 
                                                                WCF.Binding mseBinding, SqlTransaction txn, SqlConnection conn)
        {

            // Create the wsdl:portType section of the WSDL
            WSDL.PortType portType = new System.Web.Services.Description.PortType();
            portType.Name = endpoint.ServiceName;
            serviceDescription.PortTypes.Add(portType);
            WSDL.Binding binding = null;
            XmlDocument xDoc = new XmlDocument();

            // Create this section only if Soap11 & Soap12
            if (mseBinding.MessageVersion.Envelope != EnvelopeVersion.None)
            {
                // Create the Binding
                binding = new System.Web.Services.Description.Binding();
                binding.Name = string.Format("{0}Soap", endpoint.ServiceName);
                binding.Type = new XmlQualifiedName(string.Format("tns:{0}Soap", endpoint.ServiceName));

                if (mseBinding.MessageVersion.Envelope == EnvelopeVersion.Soap11)
                {
                    WSDL.SoapBinding soapBinding = new WSDL.SoapBinding();
                    soapBinding.Transport = WSDL.SoapBinding.HttpTransport;
                    binding.Extensions.Add(soapBinding);
                }
                else
                {
                    WSDL.Soap12Binding soapBinding = new WSDL.Soap12Binding();
                    soapBinding.Transport = WSDL.Soap12Binding.HttpTransport;
                    binding.Extensions.Add(soapBinding);
                }
                serviceDescription.Bindings.Add(binding);
            }

            foreach (OperationVersionListElement element in publishedOpVers.OperationVersions)
            {
                OperationVersion opVersion = GetOperationVersion(element.ID, txn, conn);
                string opName = opVersion.OperationName;

                WSDL.Operation operation = new System.Web.Services.Description.Operation();
                operation.Name = opName;
                portType.Operations.Add(operation);

                WSDL.OperationBinding operationbinding = null;
                // Create this section only if Soap11 & Soap12
                if (mseBinding.MessageVersion.Envelope != EnvelopeVersion.None)
                {
                    operationbinding = new System.Web.Services.Description.OperationBinding();
                    operationbinding.Name = opName;
                }

                if (opVersion.RequestMsg != null && opVersion.RequestMsg.Count > 0)
                {
                    WSDL.Message message = new System.Web.Services.Description.Message();
                    message.Name = string.Format("{0}SoapIn", opName);
                    int counter = 0;
                    foreach (MessagePart part in opVersion.RequestMsg)
                    {
                        WSDL.MessagePart messagePart = new System.Web.Services.Description.MessagePart();
                        messagePart.Element = new XmlQualifiedName(part.ElementName, part.NamespaceURI);
                        messagePart.Name = string.Format("{0}RequestPart{1}", part.ElementName, counter);
                        //messagePart.Name = "parameters";
                        message.Parts.Add(messagePart);
                        counter++;
                    }
                    serviceDescription.Messages.Add(message);

                    WSDL.OperationInput operationInput = new WSDL.OperationInput();
                    operationInput.Message = new XmlQualifiedName("tns:" + message.Name);
                    operation.Messages.Add(operationInput);

                    // Create this section only if Soap11 & Soap12
                    if (mseBinding.MessageVersion.Envelope != EnvelopeVersion.None)
                    {
                        WSDL.InputBinding inputBinding = new System.Web.Services.Description.InputBinding();
                        operationbinding.Input = inputBinding;
                        if (mseBinding.MessageVersion.Envelope == EnvelopeVersion.Soap11)
                        {
                            WSDL.SoapBodyBinding soapBodyBinding = new System.Web.Services.Description.SoapBodyBinding();
                            soapBodyBinding.Use = System.Web.Services.Description.SoapBindingUse.Literal;
                            inputBinding.Extensions.Add(soapBodyBinding);
                        }
                        else
                        {
                            WSDL.Soap12BodyBinding soapBodyBinding = new System.Web.Services.Description.Soap12BodyBinding();
                            soapBodyBinding.Use = System.Web.Services.Description.SoapBindingUse.Literal;
                            inputBinding.Extensions.Add(soapBodyBinding);
                        }
                    }
                }
                if (opVersion.ResponseMsg != null && opVersion.ResponseMsg.Count > 0)
                {
                    WSDL.Message message = new System.Web.Services.Description.Message();
                    message.Name = string.Format("{0}SoapOut", opName);
                    int counter = 0;
                    foreach (MessagePart part in opVersion.ResponseMsg)
                    {
                        WSDL.MessagePart messagePart = new System.Web.Services.Description.MessagePart();
                        messagePart.Element = new XmlQualifiedName(part.ElementName, part.NamespaceURI);
                        messagePart.Name = string.Format("{0}ResponsePart{1}",part.ElementName,counter);
                        //messagePart.Name = "parameters";
                        message.Parts.Add(messagePart);
                        counter++;
                    }
                    serviceDescription.Messages.Add(message);

                    WSDL.OperationOutput operationOutput = new WSDL.OperationOutput();
                    operationOutput.Message = new XmlQualifiedName("tns:" + message.Name);
                    operation.Messages.Add(operationOutput);

                    // Create this section only if Soap11 & Soap12
                    if (mseBinding.MessageVersion.Envelope != EnvelopeVersion.None)
                    {
                        WSDL.OutputBinding outputBinding = new System.Web.Services.Description.OutputBinding();
                        operationbinding.Output = outputBinding;
                        if (mseBinding.MessageVersion.Envelope == EnvelopeVersion.Soap11)
                        {
                            WSDL.SoapBodyBinding soapBodyBinding = new System.Web.Services.Description.SoapBodyBinding();
                            soapBodyBinding.Use = System.Web.Services.Description.SoapBindingUse.Literal;
                            outputBinding.Extensions.Add(soapBodyBinding);
                        }
                        else
                        {
                            WSDL.Soap12BodyBinding soapBodyBinding = new System.Web.Services.Description.Soap12BodyBinding();
                            soapBodyBinding.Use = System.Web.Services.Description.SoapBindingUse.Literal;
                            outputBinding.Extensions.Add(soapBodyBinding);
                        }
                    }
                }

                // Create this section only if Soap11 & Soap12
                if (mseBinding.MessageVersion.Envelope != EnvelopeVersion.None)
                {
                    WSDL.SoapOperationBinding soapOperationBinding = new WSDL.SoapOperationBinding();
                    soapOperationBinding.Style = WSDL.SoapBindingStyle.Document;
                    soapOperationBinding.SoapAction = opName;
                    operationbinding.Extensions.Add(soapOperationBinding);
                }
                if (opVersion.SoapFaults != null && opVersion.SoapFaults.Count > 0)
                {
                    foreach (SoapFault fault in opVersion.SoapFaults)
                    {
                        WSDL.Message message = new System.Web.Services.Description.Message();
                        message.Name = string.Format("{0}_{1}_FaultMessage", opName, fault.Name);

                        WSDL.MessagePart messagePart = new System.Web.Services.Description.MessagePart();
                        messagePart.Element = new XmlQualifiedName(fault.ElementName, fault.NamespaceURI);
                        messagePart.Name = "detail";

                        message.Parts.Add(messagePart);
                        serviceDescription.Messages.Add(message);

                        WSDL.OperationFault operationFault = new WSDL.OperationFault();
                        operationFault.Name = fault.Name;
                        operationFault.Message = new XmlQualifiedName("tns:" + message.Name);
                        // Create the WSAddressing's Action attribute
                        XmlAttribute action = xDoc.CreateAttribute("wsaw", "Action", "http://www.w3.org/2006/05/addressing/wsdl");
                        action.Value = fault.Action;
                        operationFault.ExtensibleAttributes = new XmlAttribute[] { action };
                        operation.Faults.Add(operationFault);

                        // Create this section only if Soap11 & Soap12
                        if (mseBinding.MessageVersion.Envelope != EnvelopeVersion.None)
                        {
                            WSDL.FaultBinding faultBinding = new WSDL.FaultBinding();
                            faultBinding.Name = fault.Name;
                            if (mseBinding.MessageVersion.Envelope == EnvelopeVersion.Soap11)
                            {
                                WSDL.SoapFaultBinding soapFaultBinding = new WSDL.SoapFaultBinding();
                                soapFaultBinding.Name = fault.Name;
                                soapFaultBinding.Namespace = null;
                                soapFaultBinding.Use = System.Web.Services.Description.SoapBindingUse.Literal;
                                faultBinding.Extensions.Add(soapFaultBinding);
                            }
                            else
                            {
                                WSDL.Soap12FaultBinding soapFaultBinding = new WSDL.Soap12FaultBinding();
                                soapFaultBinding.Name = fault.Name;
                                soapFaultBinding.Namespace = null; 
                                soapFaultBinding.Use = System.Web.Services.Description.SoapBindingUse.Literal;
                                faultBinding.Extensions.Add(soapFaultBinding);
                            }
                            operationbinding.Faults.Add(faultBinding);
                        }
                    }
                }
                // Create this section only if Soap11 & Soap12
                if (mseBinding.MessageVersion.Envelope != EnvelopeVersion.None)
                {
                    binding.Operations.Add(operationbinding);
                }
            }

            // Create this section only if Soap11 & Soap12
            // This section will be overwritten by the one from the Runtime
            //if (mseBinding.MessageVersion.Envelope != EnvelopeVersion.None)
            //{
            //    WSDL.Service service = new System.Web.Services.Description.Service();
            //    service.Name = endpoint.ServiceName;

            //    WSDL.Port port = new WSDL.Port();
            //    port.Name = string.Format("{0}Soap", endpoint.ServiceName);
            //    port.Binding = new XmlQualifiedName(string.Format("tns:{0}Soap", endpoint.ServiceName));

            //    if (mseBinding.MessageVersion.Envelope == EnvelopeVersion.Soap11)
            //    {
            //        // Create a SoapAddress extensibility element to add to the port.
            //        WSDL.SoapAddressBinding soapAddressBinding = new WSDL.SoapAddressBinding();
            //        soapAddressBinding.Location = serviceUri.ToString();
            //        port.Extensions.Add(soapAddressBinding);
            //    }
            //    else
            //    {
            //        // Create a SoapAddress extensibility element to add to the port.
            //        WSDL.Soap12AddressBinding soapAddressBinding = new WSDL.Soap12AddressBinding();
            //        soapAddressBinding.Location = serviceUri.ToString();
            //        port.Extensions.Add(soapAddressBinding);
            //    }
            //    service.Ports.Add(port);
            //    serviceDescription.Services.Add(service);
            //}
        }
        /// <summary>
        /// Converts WSDL into string
        /// </summary>
        /// <param name="wsdl"></param>
        /// <returns></returns>
        private static string ConvertWSDLToString(WSDL.ServiceDescription wsdl)
        {
            StringBuilder metadataXml = new StringBuilder();
            XmlWriterSettings xws = new XmlWriterSettings();
            xws.Indent = true;

            XmlWriter xw = XmlWriter.Create(metadataXml);
            wsdl.Write(xw);
            xw.Flush();
            return metadataXml.ToString();
        }
        /// <summary>
        /// Build service information from the EndPoint
        /// </summary>
        /// <param name="endpoint"></param>
        /// <param name="virtualServiceName"></param>
        /// <param name="serviceUri"></param>
        /// <param name="mseBinding"></param>
        /// <returns></returns>
        private static string CreateServiceInformation(Endpoint endpoint, ref string virtualServiceName, ref Uri serviceUri, ref WCF.Binding mseBinding)
        {
            string virtualServiceNS = "";

            if (string.IsNullOrEmpty(endpoint.NamespaceURI) == true)
            {
                mseBinding = BindingHelper.DeserializeBinding(endpoint.Binding.BindingConfig);
                try
                {
                    serviceUri = new Uri(mseBinding.Scheme.ToString() + "://" + endpoint.Address);
                }
                catch (Exception ex)
                {
                    throw new ApplicationException(string.Format("Failed to create service Uri due to error. Endpoint address may be invalid [{0}]", endpoint.Address), ex);
                }
                if (string.IsNullOrEmpty(endpoint.ServiceName) == false)
                    virtualServiceName = endpoint.ServiceName;
                else
                {
                    double number;
                    if (Double.TryParse(Convert.ToString(serviceUri.DnsSafeHost.Substring(0, 1), CultureInfo.InvariantCulture), System.Globalization.NumberStyles.Any, NumberFormatInfo.InvariantInfo, out number))
                        virtualServiceName = "WS" + serviceUri.DnsSafeHost;
                    else
                        virtualServiceName = serviceUri.DnsSafeHost;
                }
                virtualServiceNS = MseConstants.MSENamespace + "/" + endpoint.Binding.Name + "/" + virtualServiceName;
            }
            else
            {
                virtualServiceNS = endpoint.NamespaceURI;
            }
            return virtualServiceNS;
        }
        #endregion

        #region NZ Code Added for Schema Import/Add/Update/Delete Functions

        private static bool CheckIfSchemaObjectsEqual(SchemaObject inputSchemaObject, SchemaObject existingSchemaObject)
        {
            if (string.Compare(inputSchemaObject.Name, existingSchemaObject.Name, false) == 0 &&
                string.Compare(inputSchemaObject.NamespaceUri, existingSchemaObject.NamespaceUri, false) == 0 &&
                inputSchemaObject.Type == existingSchemaObject.Type &&
                CheckIfSchemaObjectsXmlEqual(inputSchemaObject.Xml, existingSchemaObject.Xml) == true)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        private static bool CheckIfSchemaObjectsXmlEqual(XmlElement inputNode, XmlElement existingNode)
        {
            bool areEqual = true;

            // Number of Child Nodes is different 
            if (inputNode.ChildNodes.Count != existingNode.ChildNodes.Count)
            {
                areEqual = false;
                return areEqual;
            }
            // Number of Attributes is different 
            if (inputNode.Attributes.Count != existingNode.Attributes.Count)
            {
                areEqual = false;
                return areEqual;
            }

            // Compare the inner text if nodes have no childres
            if (inputNode.ChildNodes.Count == 0 && existingNode.ChildNodes.Count == 0)
            {
                if (String.Compare(inputNode.InnerText, existingNode.InnerText, false) != 0)
                {
                    areEqual = false;
                    return areEqual;
                }
            }

            // Compare Attribuet contents
            if (inputNode.Attributes.Count > 0)
            {
                for (int counter = 0; counter < inputNode.Attributes.Count; counter++)
                {
                    XmlAttribute inputAttributeNode = inputNode.Attributes[counter];
                    if (existingNode.Attributes.GetNamedItem(inputAttributeNode.Name) != null)
                    {
                        // Attribute values do not match
                        XmlAttribute existingAttributeNode = (XmlAttribute)existingNode.Attributes.GetNamedItem(inputAttributeNode.Name);
                        if (string.Compare(inputAttributeNode.Value, existingAttributeNode.Value, false) != 0)
                        {
                            areEqual = false;
                            return areEqual;
                        }
                    }
                    else
                    {
                        // Attribute does not exist
                        areEqual = false;
                        return areEqual;
                    }
                }
            }

            // Compare Node contents
            if (inputNode.ChildNodes.Count > 0)
            {
                for (int counter = 0; counter < inputNode.ChildNodes.Count; counter++)
                {
                    XmlNode inputChildNode = inputNode.ChildNodes[counter];
                    if (existingNode.ChildNodes.Count >  counter)
                    {
                        // Attribute values do not match
                        XmlNode existingChildNode = (XmlNode)existingNode.ChildNodes[counter];
                        if (inputChildNode is XmlElement && existingChildNode is XmlElement)
                        {
                            if (CheckIfSchemaObjectsXmlEqual((XmlElement)inputChildNode, (XmlElement)existingChildNode) == false)
                            {
                                areEqual = false;
                                return areEqual;
                            }
                        }
                        else if (string.Compare(inputChildNode.GetType().FullName,existingChildNode.GetType().FullName,true) != 0)
                        {
                            areEqual = false;
                            return areEqual;
                        }
                    }
                    else
                    {
                        // Node does not exist
                        areEqual = false;
                        return areEqual;
                    }
                }
            }
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="schema"></param>
        /// <returns></returns>
        private static void CollectRealatedSchemas(Schema schema, Dictionary<string, Schema> schemaHash, 
                                                    SqlTransaction txn, SqlConnection conn)
        {
            try
            {
                schemaHash.Add(schema.NamespaceURI, schema);
                if (schema.ImportedSchemas != null && schema.ImportedSchemas.Count > 0)
                {
                    foreach (SchemaImport si in schema.ImportedSchemas)
                    {
                        if (schemaHash.ContainsKey(si.NamespaceURI) == false)
                        {
                            Schema importSchema = GetSchemaByNamespace(si.NamespaceURI, null, null);
                            schemaHash.Add(si.NamespaceURI, importSchema);
                        }
                    }
                }
                if (schema.ID != Guid.Empty)
                {
                    SchemaList schemaList = ListDependencySchemas(schema.ID, null, null);
                    if (schemaList.Schemas != null && schemaList.Schemas.Count > 0)
                    {
                        foreach (SchemaListElement schemaListElement in schemaList.Schemas)
                        {
                            if (schemaHash.ContainsKey(schemaListElement.Name) == false)
                            {
                                Schema dependentSchema = GetSchema(schemaListElement.ID, null, null);
                                schemaHash.Add(schemaListElement.Name, dependentSchema);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("An error occurred while building related schema list from MSE Schema [{0}]", schema.NamespaceURI), ex);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="schema"></param>
        /// <param name="schemaHash"></param>
        /// <param name="schemaIDs"></param>
        /// <param name="xssImport"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        private static void CollectRealatedSchemas(Schema schema, Dictionary<string, Guid> schemaHash, List<Guid> schemaIDs,
                                                    XmlSchemaSet xssImport, SqlTransaction txn, SqlConnection conn)
        {
            try
            {
                Dictionary<string, Schema> relatedSchemas = new Dictionary<string, Schema>();
                CollectRealatedSchemas(schema, relatedSchemas, txn,conn);
                foreach (Schema relatedSchema in relatedSchemas.Values)
                {
                    XmlSchema xs = CreateXmlSchemaFromSchema(relatedSchema, false);
                    schemaIDs.Add(relatedSchema.ID);
                    schemaHash.Add(relatedSchema.NamespaceURI, relatedSchema.ID);
                    if (xssImport.Contains(relatedSchema.NamespaceURI) == false)
                        xssImport.Add(xs);
                }
                xssImport.Compile();
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("An error occurred while building Related XmlSchemaSet for Schema [{0}] due to error [{1}]", schema.NamespaceURI, DAL.GetExceptionDetails(ex)));
            }
        }
        private static XmlSchema CreateXmlSchemaFromSchema(Schema schema, bool addImports)
        {
            try
            {
                XmlDocument schemaDoc = null;
                XmlSchemaSet xss = new XmlSchemaSet();
                XmlSchema xmlSchema = new XmlSchema();
                xmlSchema.TargetNamespace = schema.NamespaceURI;
                xmlSchema.ElementFormDefault = XmlSchemaForm.Qualified;

                if (addImports == true)
                {
                    if (schema.ImportedSchemas != null && schema.ImportedSchemas.Count > 0)
                    {
                        schemaDoc = ConverXmlSchemaToDOM(xmlSchema);
                        foreach (SchemaImport si in schema.ImportedSchemas)
                        {
                            XmlElement xeImport = schemaDoc.CreateElement(schemaDoc.DocumentElement.Prefix, "import", schemaDoc.DocumentElement.NamespaceURI);
                            XmlAttribute xaNamespace = xeImport.Attributes.Append(schemaDoc.CreateAttribute("namespace"));
                            xaNamespace.Value = si.NamespaceURI;
                            schemaDoc.DocumentElement.AppendChild(xeImport);
                        }
                        xmlSchema = LoadXmlSchemaFromString(schemaDoc.OuterXml);
                    }
                }
                if (schema.Objects != null && schema.Objects.Count > 0)
                {
                    foreach (SchemaObject so in schema.Objects)
                    {
                        XmlSchemaObject xso = DeSerializeSchemaObject(so.Xml.OuterXml, new XmlQualifiedName(so.Name, schema.NamespaceURI));
                        xmlSchema.Items.Add(xso);
                    }
                }
                else
                {
                    xmlSchema = LoadXmlSchemaFromString(schema.XSD.OuterXml);
                }

                return xmlSchema;
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("An error occurred while building XmlSchema from MSE Schema [{0}]", schema.NamespaceURI),ex);
            }
        }

        /// <summary>
        /// Imports all the schemas into ServiceCatalog
        /// </summary>
        /// <param name="importedSchemas"></param>
        /// <returns></returns>
        public static List<Guid> ImportSchemas(List<Schema> importedSchemas, SqlTransaction txn, SqlConnection conn)
        {
            Dictionary<string, Guid> schemaHash = new Dictionary<string, Guid>();
            Dictionary<string, Guid> mappedElemntHash = new Dictionary<string, Guid>();
            List<Guid> schemaIDs = new List<Guid>();
            XmlSchemaSet xssImport = new XmlSchemaSet();

            bool autoclose = false;

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                } 
                
                foreach (Schema schema in importedSchemas)
                {
                    XmlSchema xs = LoadXmlSchemaFromString(schema.XSD.OuterXml);
                    Guid schemaID = GetIDFromName(schema.NamespaceURI, EntityClass.Schema, txn, conn);
                    if (schemaID == null || schemaID == Guid.Empty)
                    {
                        schemaID = CreateSchemaNamespace(schema, txn, conn);
                    }
                    else
                    {
                        schema.ID = schemaID;
                        DeleteSchemaImport(schema.ID, txn, conn);
                    }
                    if (schema.ImportedSchemas != null && schema.ImportedSchemas.Count > 0)
                    {
                        foreach (SchemaImport schemaImport in schema.ImportedSchemas)
                        {
                            UpdateSchemaImport(schema.ID, schemaImport, txn, conn);
                        }
                    }
                    schemaIDs.Add(schemaID);
                    schemaHash.Add(schema.NamespaceURI, schemaID);
                    xssImport.Add(xs);
                }
                xssImport.Compile();

                foreach (XmlSchema xs in xssImport.Schemas())
                {
                    CreateSchemaObjectsFromXmlSchema(xssImport, xs, mappedElemntHash, schemaHash, txn, conn);
                }
                if ((autoclose) && (txn != null)) txn.Commit();

            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format("An error occurred while saving Schema and Objects for Import [{0}]", DAL.GetExceptionDetails(ex)));
            }

            return schemaIDs;
        }
        /// <summary>
        /// This function is called recursively to create/update objects of a schema
        /// </summary>
        /// <param name="xsSet"></param>
        /// <param name="typeName"></param>
        /// <param name="inputSchemaObject"></param>
        /// <param name="addToSchema"></param>
        /// <param name="metaType"></param>
        /// <param name="schemaHash"></param>
        /// <param name="mappedTypeHash"></param>
        /// <param name="referenceID"></param>
        private static void CollectSchemaTypes(XmlSchemaSet xsSet, XmlQualifiedName typeName, XmlSchemaObject inputSchemaObject, bool addToSchema,
                                SchemaObjectType metaType, Dictionary<string, Guid> schemaHash, Dictionary<string, Guid> mappedTypeHash,
                                Guid referenceID, SqlTransaction txn, SqlConnection conn)
        {
            if (inputSchemaObject == null)
            {
                switch (metaType)
                {
                    case SchemaObjectType.Element:
                        inputSchemaObject = xsSet.GlobalElements[typeName];
                        break;

                    case SchemaObjectType.Attribute:
                        inputSchemaObject = xsSet.GlobalAttributes[typeName];
                        break;

                    case SchemaObjectType.AttributeGroup:
                        inputSchemaObject = GetAttributeFromSchmea(xsSet, typeName); ;
                        break;

                    case SchemaObjectType.ComplexType:
                    case SchemaObjectType.SimpleType:
                    case SchemaObjectType.Unknown:
                        inputSchemaObject = xsSet.GlobalTypes[typeName];
                        metaType = GetSchemaObjectType(inputSchemaObject);
                        break;
                }
            }
            if (typeName != null && addToSchema == true)
            {
                bool found = false;
                referenceID = SaveSchemaObjectToDatabase(typeName, referenceID, inputSchemaObject, metaType, schemaHash, mappedTypeHash, txn, conn, out found);
                // SchemaObject arealy exists 
                if (found == true) return;
            }
            if (inputSchemaObject != null)
            {
                if (inputSchemaObject is XmlSchemaAttribute)
                {
                    XmlSchemaAttribute xsAttribute = inputSchemaObject as XmlSchemaAttribute;
                    if (xsAttribute.RefName != null && xsAttribute.RefName.IsEmpty == false)
                    {
                        CollectSchemaTypes(xsSet, xsAttribute.RefName, null, true, SchemaObjectType.Attribute, schemaHash, mappedTypeHash, referenceID,txn, conn);
                    }
                    else
                    {
                        if (xsAttribute.SchemaTypeName != null)
                        {
                            CollectSchemaTypes(xsSet, xsAttribute.SchemaTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else
                        {
                            if (xsAttribute.SchemaType != null)
                            {
                                CollectSchemaTypes(xsSet, null, xsAttribute.SchemaType, false, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                        }
                    }
                    return;
                }

                if (inputSchemaObject is XmlSchemaAttributeGroup)
                {
                    XmlSchemaAttributeGroup xsAttributeGroup = inputSchemaObject as XmlSchemaAttributeGroup;
                    foreach (XmlSchemaObject attributeObject in xsAttributeGroup.Attributes)
                    {
                        if (attributeObject is XmlSchemaAttributeGroupRef)
                        {
                            XmlSchemaAttributeGroupRef xsGroupRef = attributeObject as XmlSchemaAttributeGroupRef;
                            CollectSchemaTypes(xsSet, xsGroupRef.RefName, null, true, SchemaObjectType.AttributeGroup, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else
                            CollectSchemaTypes(xsSet, null, attributeObject, false, SchemaObjectType.Attribute, schemaHash, mappedTypeHash, referenceID, txn, conn);
                    }
                    return;
                }

                if (inputSchemaObject is XmlSchemaSimpleType)
                {
                    XmlSchemaSimpleType xsSimpleType = inputSchemaObject as XmlSchemaSimpleType;
                    CollectSchemaTypes(xsSet, null, xsSimpleType.Content, false, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                    return;
                }

                if (inputSchemaObject is XmlSchemaSimpleContentExtension)
                {
                    XmlSchemaSimpleContentExtension xsSimpleContentExtension = inputSchemaObject as XmlSchemaSimpleContentExtension;

                    CollectSchemaTypes(xsSet, xsSimpleContentExtension.BaseTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);

                    foreach (XmlSchemaObject attributeObject in xsSimpleContentExtension.Attributes)
                    {
                        if (attributeObject is XmlSchemaAttribute)
                        {
                            XmlSchemaAttribute xsAttribute = attributeObject as XmlSchemaAttribute;
                            if (xsAttribute.RefName != null && xsAttribute.RefName.IsEmpty == false)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.RefName, null, true, SchemaObjectType.Attribute, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                            else if (xsAttribute.SchemaTypeName != null)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.SchemaTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                        }
                        else if (attributeObject is XmlSchemaAttributeGroupRef)
                        {
                            XmlSchemaAttributeGroupRef xsAttributeGroupRef = attributeObject as XmlSchemaAttributeGroupRef;
                            CollectSchemaTypes(xsSet, xsAttributeGroupRef.RefName, null, true, SchemaObjectType.AttributeGroup, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                    return;
                }

                if (inputSchemaObject is XmlSchemaSimpleContentRestriction)
                {
                    XmlSchemaSimpleContentRestriction xsSimpleContentRestriction = inputSchemaObject as XmlSchemaSimpleContentRestriction;
                    CollectSchemaTypes(xsSet, xsSimpleContentRestriction.BaseTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);

                    foreach (XmlSchemaObject attributeObject in xsSimpleContentRestriction.Attributes)
                    {
                        if (attributeObject is XmlSchemaAttribute)
                        {
                            XmlSchemaAttribute xsAttribute = attributeObject as XmlSchemaAttribute;
                            if (xsAttribute.RefName != null && xsAttribute.RefName.IsEmpty == false)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.RefName, null, true, SchemaObjectType.Attribute, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                            else if (xsAttribute.SchemaTypeName != null)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.SchemaTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                        }
                        else if (attributeObject is XmlSchemaAttributeGroupRef)
                        {
                            XmlSchemaAttributeGroupRef xsAttributeGroupRef = attributeObject as XmlSchemaAttributeGroupRef;
                            CollectSchemaTypes(xsSet, xsAttributeGroupRef.RefName, null, true, SchemaObjectType.AttributeGroup, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                    return;
                }

                if (inputSchemaObject is XmlSchemaComplexContentExtension)
                {
                    XmlSchemaComplexContentExtension xsComplexContentExtension = inputSchemaObject as XmlSchemaComplexContentExtension;
                    CollectSchemaTypes(xsSet, xsComplexContentExtension.BaseTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);

                    foreach (XmlSchemaObject attributeObject in xsComplexContentExtension.Attributes)
                    {
                        if (attributeObject is XmlSchemaAttribute)
                        {
                            XmlSchemaAttribute xsAttribute = attributeObject as XmlSchemaAttribute;
                            if (xsAttribute.RefName != null && xsAttribute.RefName.IsEmpty == false)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.RefName, null, true, SchemaObjectType.Attribute, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                            else if (xsAttribute.SchemaTypeName != null)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.SchemaTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                        }
                        else if (attributeObject is XmlSchemaAttributeGroupRef)
                        {
                            XmlSchemaAttributeGroupRef xsAttributeGroupRef = attributeObject as XmlSchemaAttributeGroupRef;
                            CollectSchemaTypes(xsSet, xsAttributeGroupRef.RefName, null, true, SchemaObjectType.AttributeGroup, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                    if (xsComplexContentExtension.Particle != null)
                    {
                        if (xsComplexContentExtension.Particle is XmlSchemaSequence)
                        {
                            XmlSchemaSequence xsSequence = xsComplexContentExtension.Particle as XmlSchemaSequence;
                            CollectSchemaTypes(xsSet, null, xsSequence, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else if (xsComplexContentExtension.Particle is XmlSchemaChoice)
                        {
                            XmlSchemaChoice xsChoice = xsComplexContentExtension.Particle as XmlSchemaChoice;
                            CollectSchemaTypes(xsSet, null, xsChoice, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                    return;
                }

                if (inputSchemaObject is XmlSchemaComplexContentRestriction)
                {
                    XmlSchemaComplexContentRestriction xsComplexContentRestriction = inputSchemaObject as XmlSchemaComplexContentRestriction;
                    CollectSchemaTypes(xsSet, xsComplexContentRestriction.BaseTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);

                    foreach (XmlSchemaObject attributeObject in xsComplexContentRestriction.Attributes)
                    {
                        if (attributeObject is XmlSchemaAttribute)
                        {
                            XmlSchemaAttribute xsAttribute = attributeObject as XmlSchemaAttribute;
                            if (xsAttribute.RefName != null && xsAttribute.RefName.IsEmpty == false)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.RefName, null, true, SchemaObjectType.Attribute, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                            else if (xsAttribute.SchemaTypeName != null)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.SchemaTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                        }
                        else if (attributeObject is XmlSchemaAttributeGroupRef)
                        {
                            XmlSchemaAttributeGroupRef xsAttributeGroupRef = attributeObject as XmlSchemaAttributeGroupRef;
                            CollectSchemaTypes(xsSet, xsAttributeGroupRef.RefName, null, true, SchemaObjectType.AttributeGroup, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                    return;
                }

                if (inputSchemaObject is XmlSchemaElement)
                {
                    XmlSchemaElement xsElement = inputSchemaObject as XmlSchemaElement;
                    if (xsElement.RefName != null && xsElement.RefName.IsEmpty == false)
                    {
                        CollectSchemaTypes(xsSet, xsElement.RefName, null, true, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                    }
                    else
                    {
                        if (xsElement.SchemaType != null)
                        {
                            CollectSchemaTypes(xsSet, null, xsElement.SchemaType, false, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else
                        {
                            if (xsElement.SchemaTypeName != null)
                            {
                                CollectSchemaTypes(xsSet, xsElement.SchemaTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                        }
                    }
                    return;
                }

                if (inputSchemaObject is XmlSchemaComplexType)
                {
                    XmlSchemaComplexType xsComplexType = inputSchemaObject as XmlSchemaComplexType;
                    foreach (XmlSchemaObject attributeObject in xsComplexType.Attributes)
                    {
                        if (attributeObject is XmlSchemaAttribute)
                        {
                            XmlSchemaAttribute xsAttribute = attributeObject as XmlSchemaAttribute;
                            if (xsAttribute.RefName != null && xsAttribute.RefName.IsEmpty == false)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.RefName, null, true, SchemaObjectType.Attribute, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                            else if (xsAttribute.SchemaTypeName != null)
                            {
                                CollectSchemaTypes(xsSet, xsAttribute.SchemaTypeName, null, true, SchemaObjectType.Unknown, schemaHash, mappedTypeHash, referenceID, txn, conn);
                            }
                        }
                        else if (attributeObject is XmlSchemaAttributeGroupRef)
                        {
                            XmlSchemaAttributeGroupRef xsAttributeGroupRef = attributeObject as XmlSchemaAttributeGroupRef;
                            CollectSchemaTypes(xsSet, xsAttributeGroupRef.RefName, null, true, SchemaObjectType.AttributeGroup, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                    if (xsComplexType.Particle != null)
                    {
                        if (xsComplexType.Particle is XmlSchemaSequence)
                        {
                            XmlSchemaSequence xsSequence = xsComplexType.Particle as XmlSchemaSequence;
                            CollectSchemaTypes(xsSet, null, xsSequence, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else if (xsComplexType.Particle is XmlSchemaChoice)
                        {
                            XmlSchemaChoice xsChoice = xsComplexType.Particle as XmlSchemaChoice;
                            CollectSchemaTypes(xsSet, null, xsChoice, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                    else if (xsComplexType.ContentModel != null)
                    {
                        if (xsComplexType.ContentModel is XmlSchemaComplexContent)
                        {
                            XmlSchemaComplexContent xsComplexContent = xsComplexType.ContentModel as XmlSchemaComplexContent;
                            // It is either extension or restriction
                            CollectSchemaTypes(xsSet, null, xsComplexContent.Content, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else
                        {
                            XmlSchemaSimpleContent xsSimpleContent = xsComplexType.ContentModel as XmlSchemaSimpleContent;
                            // It is either extension or restriction
                            CollectSchemaTypes(xsSet, null, xsSimpleContent.Content, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                }

                if (inputSchemaObject is XmlSchemaSequence)
                {
                    XmlSchemaSequence xsSequence = inputSchemaObject as XmlSchemaSequence;
                    foreach (XmlSchemaObject sequenceObject in xsSequence.Items)
                    {
                        if (sequenceObject is XmlSchemaElement)
                        {
                            XmlSchemaElement xsItemElement = sequenceObject as XmlSchemaElement;
                            CollectSchemaTypes(xsSet, xsItemElement.QualifiedName, xsItemElement, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else if (sequenceObject is XmlSchemaSequence)
                        {
                            XmlSchemaSequence xsItemSequence = sequenceObject as XmlSchemaSequence;
                            CollectSchemaTypes(xsSet, null, xsItemSequence, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else if (sequenceObject is XmlSchemaGroup)
                        {
                            XmlSchemaGroup xsItemGroup = sequenceObject as XmlSchemaGroup;
                            CollectSchemaTypes(xsSet, xsItemGroup.QualifiedName, xsItemGroup, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else
                        {
                            CollectSchemaTypes(xsSet, null, sequenceObject, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                }

                if (inputSchemaObject is XmlSchemaChoice)
                {
                    XmlSchemaChoice xsChoice = inputSchemaObject as XmlSchemaChoice;
                    foreach (XmlSchemaObject choiceObject in xsChoice.Items)
                    {
                        if (choiceObject is XmlSchemaElement)
                        {
                            XmlSchemaElement xsItemElement = choiceObject as XmlSchemaElement;
                            CollectSchemaTypes(xsSet, xsItemElement.QualifiedName, xsItemElement, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else if (choiceObject is XmlSchemaSequence)
                        {
                            XmlSchemaSequence xsItemSequence = choiceObject as XmlSchemaSequence;
                            CollectSchemaTypes(xsSet, null, xsItemSequence, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else if (choiceObject is XmlSchemaGroup)
                        {
                            XmlSchemaGroup xsItemGroup = choiceObject as XmlSchemaGroup;
                            CollectSchemaTypes(xsSet, xsItemGroup.QualifiedName, null, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                        else
                        {
                            CollectSchemaTypes(xsSet, null, choiceObject, false, SchemaObjectType.Element, schemaHash, mappedTypeHash, referenceID, txn, conn);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Loads Schema from String
        /// </summary>
        /// <param name="schemaXml"></param>
        /// <returns></returns>
        private static XmlSchema LoadXmlSchemaFromString(string schemaXml)
        {
            XmlSchema xs = null;
            StringBuilder sbErrors = new StringBuilder();
            sbErrors.Append("");
            ValidationEventHandler vh = new ValidationEventHandler
            (
                delegate(object ob, ValidationEventArgs args)
                {
                    try
                    {
                        sbErrors.AppendFormat("Schema Validation Error: Exception[{0}] Message[{1}]", DAL.GetExceptionDetails(args.Exception), args.Message);
                    }
                    catch (Exception ex)
                    {
                        sbErrors.AppendFormat("Failed to Validate Schema due to error [{0}]", DAL.GetExceptionDetails(ex));
                    }
                }
            );

            xs = XmlSchema.Read(new StringReader(schemaXml), vh);
            if (sbErrors.ToString().Length > 0)
            {
                xs = null;
            }
            return xs;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="elementName"></param>
        /// <param name="parentID"></param>
        /// <param name="xso"></param>
        /// <param name="metaType"></param>
        /// <param name="schemaHash"></param>
        /// <param name="savedElemntHash"></param>
        /// <param name="found"></param>
        /// <returns></returns>
        private static Guid SaveSchemaObjectToDatabase(XmlQualifiedName objectName, Guid parentID, XmlSchemaObject xso, SchemaObjectType metaType,
                                Dictionary<string, Guid> schemaHash, Dictionary<string, Guid> savedObjectHash, SqlTransaction txn, SqlConnection conn, out bool found)
        {
            Guid objectID = Guid.Empty;
            found = false;
            if (objectName.Namespace != XmlSchema.Namespace)
            {
                if (objectName.Name.Length > 0 && objectName.Namespace.Length > 0)
                {
                    string key = CreateKey(objectName, metaType);
                    if (savedObjectHash.ContainsKey(key) == false)
                    {
                        
                        SchemaObject schemaObject = new SchemaObject();
                        schemaObject.Xml = SerializeSchemaObject(xso, objectName.Namespace);
                        schemaObject.Name = objectName.Name;
                        schemaObject.Type = metaType;
                        schemaObject.NamespaceUri = objectName.Namespace;

                        SchemaObject existingSchemaObject = GetSchemaObjectByNameTypeAndNamespace(objectName.Namespace, objectName.Name, metaType, txn, conn);
                        if (existingSchemaObject != null)
                        {
                            if (CheckIfSchemaObjectsEqual(schemaObject, existingSchemaObject) == true)
                            {
                                // SchemaObject already exists and is the same as the one that we are trying to save
                                // So no need to do any saves
                                found = true;
                                objectID = existingSchemaObject.ID;
                            }
                            else
                            {
                                objectID = DAL.UpdateSchemaObject(schemaObject, existingSchemaObject.ID, parentID, schemaHash[objectName.Namespace], txn, conn);
                            }
                        }
                        else
                        {
                            objectID = DAL.CreateSchemaObject(schemaObject, parentID, schemaHash[objectName.Namespace], txn, conn);
                        }
                        savedObjectHash.Add(key, objectID);
                    }
                    else
                    {
                        objectID = savedObjectHash[key];
                        if (parentID != Guid.Empty)
                        {
                            CreateSchemaObjectDependency(objectID, parentID, txn, conn);
                        }
                        found = true;
                    }
                }
            }
            return objectID;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="qName"></param>
        /// <param name="metaType"></param>
        /// <returns></returns>
        private static string CreateKey(XmlQualifiedName qName, SchemaObjectType metaType)
        {
            return string.Format("{0}|{1}|{2}", qName.Name, qName.Namespace, metaType.ToString());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="xso"></param>
        /// <param name="schemaNamespace"></param>
        /// <returns></returns>
        private static XmlElement SerializeSchemaObject(XmlSchemaObject xso, string schemaNamespace)
        {
            XmlSchema xmlSchema = new XmlSchema();
            xmlSchema.TargetNamespace = schemaNamespace;
            xmlSchema.ElementFormDefault = XmlSchemaForm.Qualified;
            xmlSchema.Items.Add(xso);

            StringBuilder sb = new StringBuilder();
            XmlWriter xw = XmlWriter.Create(sb);
            xmlSchema.Write(xw);
            xw.Flush();

            XmlDocument schemaDoc = new XmlDocument();
            schemaDoc.LoadXml(sb.ToString());
            return (XmlElement)schemaDoc.DocumentElement;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="xmlSchema"></param>
        /// <param name="schemaNamespace"></param>
        /// <returns></returns>
        private static XmlSchema AppendImportsToSchema(Schema schema, XmlSchema xmlSchema, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[ListSchemaImports]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = schema.ID;
                    cmd.Parameters.Add(IDParam);

                    schema.ImportedSchemas = new List<SchemaImport>();
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                SchemaImport si = new SchemaImport();
                                si.NamespaceURI = reader.GetString(0);
                                si.ID = reader.GetGuid(1);
                                schema.ImportedSchemas.Add(si);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }


            if (schema.ImportedSchemas.Count > 0)
            {
                XmlDocument schemaDoc = ConverXmlSchemaToDOM(xmlSchema);
                foreach (SchemaImport si in schema.ImportedSchemas)
                {
                    XmlElement xeImport = schemaDoc.CreateElement(schemaDoc.DocumentElement.Prefix, "import", schemaDoc.DocumentElement.NamespaceURI);
                    XmlAttribute xaNamespace = xeImport.Attributes.Append(schemaDoc.CreateAttribute("namespace"));
                    xaNamespace.Value = si.NamespaceURI;
                    schemaDoc.DocumentElement.AppendChild(xeImport);
                }
                xmlSchema = LoadXmlSchemaFromString(schemaDoc.OuterXml);
            }
            return xmlSchema;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="schema"></param>
        /// <param name="xmlSchema"></param>
        /// <param name="schemaID"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        /// <returns></returns>
        private static XmlSchema AppendObjectsToSchema(Schema schema, XmlSchema xmlSchema, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[ListSchemaObjects]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = schema.ID;
                    cmd.Parameters.Add(IDParam);

                    schema.Objects  = new List<SchemaObject>();
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                SchemaObject so = new SchemaObject();
                                so.ID = reader.GetGuid(0);
                                so.Name = reader.GetString(1);
                                so.Type = (SchemaObjectType)reader.GetInt16(2);
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(3).CreateReader());
                                so.Xml = xdoc.DocumentElement;
                                schema.Objects.Add(so);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }


            if (schema.Objects.Count > 0)
            {
                foreach (SchemaObject so in schema.Objects)
                {
                    XmlSchemaObject xso = DeSerializeSchemaObject(so.Xml.OuterXml,new XmlQualifiedName(so.Name,schema.NamespaceURI));
                    xmlSchema.Items.Add(xso);
                }
            }
            return xmlSchema;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="schemaObjectID"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        /// <returns></returns>
        private static SchemaObject GetSchemaObject(Guid schemaObjectID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SchemaObject schemaObject = new SchemaObject();
            const string sprocname = "[ServiceEngine].[GetSchemaObjects]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = schemaObjectID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            reader.Read();
                            schemaObject.ID = reader.GetGuid(0);
                            schemaObject.Name = reader.GetString(1);
                            schemaObject.Type = (SchemaObjectType)reader.GetInt16(2);
                            XmlDocument xdoc = new XmlDocument();
                            xdoc.Load(reader.GetSqlXml(3).CreateReader());
                            schemaObject.Xml = xdoc.DocumentElement;
                            schemaObject.NamespaceUri = reader.GetString(4);
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return schemaObject;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="schemaObjectID"></param>
        /// <param name="txn"></param>
        /// <param name="conn"></param>
        /// <returns></returns>
        private static SchemaObject GetSchemaObjectByNameTypeAndNamespace(string namespaceUri, string name, SchemaObjectType type,
                                                                            SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            SchemaObject schemaObject = null;
            const string sprocname = "[ServiceEngine].[GetSchemaObjectByNameTypeAndNamespace]";

            try
            {
                Guid schemaID = GetIDFromName(namespaceUri, EntityClass.Schema, txn, conn);

                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter SchemaIDParam = new SqlParameter("@SchemaID", SqlDbType.UniqueIdentifier);
                    SqlParameter SchemaObjectTypeParam = new SqlParameter("@Type", SqlDbType.SmallInt);
                    SqlParameter SchemaObjectNameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 256);

                    cmd.CommandType = CommandType.StoredProcedure;

                    SchemaIDParam.Value = schemaID;
                    SchemaObjectTypeParam.Value = Convert.ToInt16(type);
                    SchemaObjectNameParam.Value = name;

                    cmd.Parameters.Add(SchemaIDParam);
                    cmd.Parameters.Add(SchemaObjectTypeParam);
                    cmd.Parameters.Add(SchemaObjectNameParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            schemaObject = new SchemaObject();
                            reader.Read();
                            schemaObject.ID = reader.GetGuid(0);
                            schemaObject.Name = reader.GetString(1);
                            schemaObject.Type = (SchemaObjectType)reader.GetInt16(2);
                            XmlDocument xdoc = new XmlDocument();
                            xdoc.Load(reader.GetSqlXml(3).CreateReader());
                            schemaObject.Xml = xdoc.DocumentElement;
                            schemaObject.NamespaceUri = reader.GetString(4);
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return schemaObject;
        }
        private static List<SchemaObject> ListSchemaObjectDependencies(Guid schemaObjectID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<SchemaObject> schemaObjects = new List<SchemaObject>();
            const string sprocname = "[ServiceEngine].[ListSchemaObjectDependencies]";

            try
            {
                if (conn == null) conn = new SqlConnection(Configurator.svcConfig.DBConnString);
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = schemaObjectID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                SchemaObject schemaObject = new SchemaObject();
                                schemaObject.ID = reader.GetGuid(0);
                                schemaObject.Name = reader.GetString(1);
                                schemaObject.Type = (SchemaObjectType)reader.GetInt16(2);
                                XmlDocument xdoc = new XmlDocument();
                                xdoc.Load(reader.GetSqlXml(3).CreateReader());
                                schemaObject.Xml = xdoc.DocumentElement;
                                schemaObject.NamespaceUri = reader.GetString(4);
                                schemaObjects.Add(schemaObject);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose) { conn.Close(); }
            }

            return schemaObjects;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="schemaXml"></param>
        /// <param name="objectName"></param>
        /// <param name="metaType"></param>
        /// <returns></returns>
        private static XmlSchemaObject DeSerializeSchemaObject(string schemaXml, XmlQualifiedName objectName)
        {
            XmlSchemaObject schemaObject = null;
            XmlSchema xmlSchema = new XmlSchema();
            xmlSchema = LoadXmlSchemaFromString(schemaXml);
            schemaObject = xmlSchema.Items[0];
            return schemaObject;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="xsObject"></param>
        /// <param name="schemaHash"></param>
        /// <param name="mappedTypeHash"></param>
        /// <returns></returns>
        private static bool AddTypeToSchemaAndHash(SchemaObject schemaObject, Dictionary<string, XmlSchema> schemaHash, Dictionary<Guid, string> mappedTypeHash)
        {
            bool existAlready = false;
            if (string.Compare(schemaObject.NamespaceUri, XmlSchema.Namespace, true) != 0)
            {
                if (mappedTypeHash.ContainsKey(schemaObject.ID) == false)
                {
                    XmlSchema xs = GetSchemaFromMap(schemaHash, schemaObject.NamespaceUri);
                    XmlSchemaObject xsObject = DeSerializeSchemaObject(schemaObject.Xml.OuterXml, new XmlQualifiedName(schemaObject.Name, schemaObject.NamespaceUri));
                    xs.Items.Add(xsObject);
                    mappedTypeHash.Add(schemaObject.ID, schemaObject.Name);
                }
                else
                {
                    existAlready = true;
                }
            }
            return existAlready;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="schemaObject"></param>
        /// <param name="schemaHash"></param>
        /// <param name="mappedTypeHash"></param>
        private static void AppendDependencyObjectsToSchema(SchemaObject schemaObject,
                                            Dictionary<string, XmlSchema> schemaHash, Dictionary<Guid, string> mappedTypeHash)
        {
            List<SchemaObject> dependencies = ListSchemaObjectDependencies(schemaObject.ID,null,null);
            if (dependencies.Count > 0)
            {
                foreach (SchemaObject key in dependencies)
                {
                    if (AddTypeToSchemaAndHash(key, schemaHash, mappedTypeHash) == false)
                    {
                        AppendDependencyObjectsToSchema(key, schemaHash, mappedTypeHash);
                    }
                }
            }
        }
        private static void AppendImportsToSchema(Schema schema, XmlDocument schemaDoc)
        {
            XmlNamespaceManager xmlns = new XmlNamespaceManager(schemaDoc.NameTable);
            xmlns.AddNamespace("xsd", XmlSchema.Namespace);
            XmlNodeList importNodes = schemaDoc.SelectNodes("//xsd:import", xmlns);
            schema.ImportedSchemas.Clear();
            foreach (XmlNode xn in importNodes)
            {
                SchemaImport si = new SchemaImport();
                si.NamespaceURI = xn.Attributes["namespace"].Value;
                schema.ImportedSchemas.Add(si);
            }
        }
        private static SchemaObjectType GetSchemaObjectType(XmlSchemaObject xmlSchemaObject)
        {
            if (xmlSchemaObject is XmlSchemaAttribute)
            {
                return SchemaObjectType.Attribute;
            }
            else if (xmlSchemaObject is XmlSchemaAttributeGroup)
            {
                return SchemaObjectType.AttributeGroup;
            }
            else if (xmlSchemaObject is XmlSchemaSimpleType)
            {
                return SchemaObjectType.SimpleType;
            }
            else if (xmlSchemaObject is XmlSchemaComplexType)
            {
                return SchemaObjectType.ComplexType;
            }
            else
            {
                return SchemaObjectType.Unknown;
            }
        }
        #endregion
    }
}

